Next.js App Router
了解如何在 Next.js App Router 中使用 Joy UI。
示例
在一个新的基于 App Router 的项目上从头开始?
通过这个示例:Joy UI - Next.js App Router with TypeScript,直接开始编码。
Next.js 和 React Server Components
Next.js App Router 实现了 React Server Components,React 即将推出的功能。
为了支持 App Router,Joy UI 中需要访问浏览器 API 的组件和钩子通过 "use client"
指令导出。
在 App Router 中使用 Joy UI
要设置 Joy UI,创建一个自定义的 ThemeRegistry
组件,它结合了 Emotion CacheProvider
、Joy UI 的 CssVarsProvider
和来自 next/navigation
的 useServerInsertedHTML
钩子,如下所示
// app/ThemeRegistry.tsx
'use client';
import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider } from '@emotion/react';
import { CssVarsProvider } from '@mui/joy/styles';
import CssBaseline from '@mui/joy/CssBaseline';
import theme from '/path/to/custom/theme'; // OPTIONAL
// This implementation is from emotion-js
// https://github.com/emotion-js/emotion/issues/2928#issuecomment-1319747902
export default function ThemeRegistry(props) {
const { options, children } = props;
const [{ cache, flush }] = React.useState(() => {
const cache = createCache(options);
cache.compat = true;
const prevInsert = cache.insert;
let inserted: string[] = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) {
return null;
}
let styles = '';
for (const name of names) {
styles += cache.inserted[name];
}
return (
<style
key={cache.key}
data-emotion={`${cache.key} ${names.join(' ')}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
});
return (
<CacheProvider value={cache}>
<CssVarsProvider theme={theme}>
{/* the custom theme is optional */}
<CssBaseline />
{children}
</CssVarsProvider>
</CacheProvider>
);
}
// app/layout.tsx
export default function RootLayout(props) {
return (
<html lang="en">
<body>
<ThemeRegistry options={{ key: 'joy' }}>{props.children}</ThemeRegistry>
</body>
</html>
);
}
Props 序列化
从服务器组件传递的 Props——例如 page.js
或其他路由文件——必须是可序列化的。