乐闻世界logo
搜索文章和话题

How to force Zustand to work on client side only?

2 个月前提问
1 个月前修改
浏览次数28

1个答案

1

在使用 Zustand 进行状态管理时,确保它仅在客户端工作是重要的,尤其是在服务器端渲染(SSR)的环境中,如 Next.js。为了达到这个目的,我们可以采取以下步骤:

1. 使用浏览器全局变量

由于 Zustand 本质上是基于 React 的,我们可以利用 React 生命周期钩子(如 useEffect)来确保 Zustand 的 store 只在浏览器环境中初始化和订阅。这是因为 useEffect 只在客户端执行。

示例代码

javascript
import create from 'zustand'; const useStore = create(set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })); const Counter = () => { const { count, increment } = useStore(); useEffect(() => { // 此处的代码只会在客户端执行 increment(); }, []); return <div>Count: {count}</div>; };

2. 区分服务器和客户端的逻辑

在 Next.js 等框架中,可以利用 typeof window 来判断当前代码是在服务器还是客户端执行。如果在服务器上执行,就不初始化或操作 Zustand 的 store。

示例代码

javascript
import create from 'zustand'; let useStore; if (typeof window !== 'undefined') { // 只在客户端初始化 store useStore = create(set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })); } else { // 在服务器上提供一个空的或只读的 store useStore = () => ({ count: 0, increment: () => {} }); } const Counter = () => { const { count, increment } = useStore(); return <div onClick={increment}>Count: {count}</div>; };

3. 使用动态导入

在 Next.js 中,还可以使用动态导入(next/dynamic)来确保组件只在客户端加载和渲染。这样可以避免在 SSR 时渲染或初始化 Zustand 相关的逻辑。

示例代码

javascript
import dynamic from 'next/dynamic'; const CounterWithStore = dynamic(() => import('../components/Counter'), { ssr: false // 确保不在服务器端渲染 }); // 使用 CounterWithStore 组件时,它将只在客户端加载和渲染

通过以上方法,可以有效地确保 Zustand 的使用仅限于客户端,从而避免在服务器端渲染时出现不必要的复杂性或潜在的错误。

2024年8月1日 12:51 回复

你的答案