Next.js
Jotai 通过 useHydrateAtoms 支持原子的水合。相关文档请参见这里。
可以将 Jotai 与路由同步。你可以通过 atomWithHash 实现:
const pageAtom = atomWithHash('page', 1, { replaceState: true, subscribe: (callback) => { Router.events.on('routeChangeComplete', callback) window.addEventListener('hashchange', callback) return () => { Router.events.off('routeChangeComplete', callback) window.removeEventListener('hashchange', callback) } },})这样你就能完全控制要订阅哪个路由事件。
在 Next.js 13 中
Section titled “在 Next.js 13 中”从 Next.js 13 开始,
Router.events.on()发生了变化,不再暴露事件。App Router Roadmap 中计划了事件拦截和 hash 处理,但目前没有具体的时间表或实现方式。目前使用atomWithHash()时,通过路由导航不会在原子中加载数据,只有在页面重新加载或组件重新渲染时才会生效。建议将setHash选项设置为replaceState,因为 Next.js 在底层似乎使用了 window.history,这样可以让用户使用浏览器的后退按钮。
服务端渲染(SSR)中不能返回 promise
Section titled “服务端渲染(SSR)中不能返回 promise”需要注意的是,在服务端渲染(SSR)中不能返回 promise。不过,你可以在原子定义中进行防护处理。
如果可能,请使用 useHydrateAtoms 从服务端水合值。
const postData = atom((get) => { const id = get(postId) if (isSSR || prefetchedPostData[id]) { return prefetchedPostData[id] || EMPTY_POST_DATA } return fetchData(id) // returns a promise})Provider
Section titled “Provider”默认情况下,Jotai 使用一个隐式的全局 store 来追踪原子的值。这就是所谓的”无 Provider”模式。在服务端渲染(SSR)场景中这会成为问题,因为全局 store 会持续存在并在多个请求之间共享,这可能导致 bug 和安全风险。
为了将 store 的生命周期限制在单个请求的范围内,你需要在应用的根部(或使用 Jotai 的子树根部)使用 Provider。
import { Provider } from 'jotai'
function App({ Component, pageProps }: AppProps) { return ( <Provider> <Component {...pageProps} /> </Provider> )}在这种情况下:
Provider会将其子树中使用的原子状态保存在自身而非全局 store 中。Provider的生命周期与应用一致,由于每次 SSR 请求都会重新创建应用,我们实际上将 store 的生命周期限制在了单个请求内。
SWC 插件
Section titled “SWC 插件”Jotai 提供了 SWC 插件,以改善使用 Next.js 开发时的体验。在 SWC 章节了解更多信息。
HN Posts
Section titled “HN Posts”Page Router 示例:
App Router 在 Stackblitz 上的示例
Next.js 仓库
Section titled “Next.js 仓库”npx create-next-app --example with-jotai with-jotai-app这是链接。