我试图在Next.js项目中的localStorage
中持久化上下文,但当我刷新页面时出现了一个水合错误。
我该如何解决这个问题?
type AppState = {
name: string;
salary: number;
info: {
email: string;
department: string;
};
};
interface Props {
children: ReactNode;
}
const initialState: AppState = {
name: "osamu1908",
salary: 2000,
info: {
email: "dynamic@gmail.com",
department: "software developer",
},
};
export const AppState = createContext<AppState>(initialState);
export const AppStateSet = createContext<Dispatch<SetStateAction<AppState>>>(
() => {}
);
const initalFromLocalStorage = () => {
if (typeof window !== "undefined") {
const result = localStorage.getItem("state");
if (result) {
return JSON.parse(result) as AppState;
}
}
return initialState;
};
const AppStateProvider = ({ children }: Props) => {
const [state, setState] = useState<AppState>(initalFromLocalStorage());
useEffect(() => {
localStorage.setItem("state", JSON.stringify(state));
}, [state]);
return (
<AppState.Provider value={state}>
<AppStateSet.Provider value={setState}>{children}</AppStateSet.Provider>
</AppState.Provider>
);
};
export default AppStateProvider;
1条答案
按热度按时间yuvru6vn1#
客户端和服务器上的初始渲染应该相同。任何时候你违反这个规则,你会得到一个hydration错误,就像在你的情况下,在服务器上没有
localStorage
,它存在于浏览器上,导致不同的初始状态。您应该将示例化主题的逻辑移动到
useEffect
中:此时,您可以简化
initalFromLocalStorage
如下: