Next.js App Router
Next.js 13.4
App Router (Stable)
使用文件系统作为 API
```js
// app/layout.js// New: App Router ✨
// The root layout is shared for the entire application
export default function RootLayout({ children }) {
return (<html lang="en"> <body>{children}</body> </html>);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 自由导入任何 CSS 文件
- 与 React Suspense 深度集成,getServerSideProps 不再阻止交互
- 默认所有组件都是 React Server 组件
- ```js
export default async function Page() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can use Date, Map, Set, etc.
const data = res.json();
return '...';
}
默认将页面标记为 transitions,使路由转换能够中断
自动代码分割
```js
import { getUser } from ‘./auth’;
import { Dashboard, Landing } from ‘./components’;export default async function Layout() {
const isLoggedIn = await getUser();
// isLoggedIn 是 false 时,不会被传输到客户端
return isLoggedIn ?: ;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- Turbopack (Beta): 使用 `next dev --turbo` 启用
- Server Actions (Alpha)
- [Server Action 的背后原理,没有魔法,只是简单函数](https://zenn.dev/cybozu_frontend/articles/server-actions-deep-dive)
- 在服务端执行任何操作,和客户端代码轻松集成,不需要再写 api 代码了
```js
import kv from './kv';
// 集成到 form
export default function Page({ params }) {
async function increment() {
'use server';
await kv.incr(`post:id:${params.id}`);
}
return (
<form action={increment}>
<button type="submit">Like</button>
</form>
);
}
自定义调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16'use client';
import { useTransition } from 'react';
import { myAction } from './action';
export function MyComponent() {
const [_, startTransition] = useTransition();
const handleClick = () => {
startTransition(async () => {
await myAction();
});
};
return <button onClick={handleClick}>Custom Invocation</button>;
}
Next.js App Router