error:[ Server ] Error: Attempted to call useAtomValue() from the server but useAtomValue is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component
当在 Next.js 中使用 Jotai 时,服务器端直接调用 Jotai 的钩子;所以我们无法直接在服务器组件中使用Jotai;那么如何解决呢?
解决方案:
1、我们需要确保 Jotai 的钩子只在客户端组件中使用,所以我们使用 'use client' 将Jotai 的使用限制在客户端组件中使用;如下图Counter组件
2、页面组件(app/page.tsx)是一个服务器组件,它不直接使用 Jotai,所以我们在page中使用上述Jotai的客户组件,如图
3、确保 Jotai 可以在整个应用中正常工作,所以我们需要向根布局节点中添加Jotai的Provider,如下图,layout是我nextJS项目的根布局
完成以上3点,就可以在nextJS项目中顺利使用Joati了;
如果需要在服务器组件中访问或设置 Jotai 状态,就像图1那样,'use client'创建一个客户端包装组件,如果存在存在初始值传递,则可以客户端组件接受 props 并与 Jotai 交互。如下:
1、声明一个客户端组件CounterWrapper,组件接收一个初始值initialValue
2、服务端页面通过属性传参
这样就可以在 Next.js 的服务器组件和客户端组件中都使用 Jotai,同时避免在服务器端直接调用 Jotai 的钩子。
关键点总结:
1. 我们将 Jotai 的使用限制在标记为 'use client' 的客户端组件中。
2. 页面组件(app/page.tsx)是一个服务器组件,它不直接使用 Jotai,而是渲染一个使用 Jotai 的客户端组件(Counter)。
3. 我们在根布局中添加了 Jotai 的 Provider,确保 Jotai 可以在整个应用中正常工作。
4. 如果你需要在服务器组件中访问或设置 Jotai 状态,你可以创建一个客户端包装组件,该组件接受 props 并与 Jotai 交互。