You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Next.js中使用localStorage持久化Context的Hydration错误?

解决Next.js中localStorage持久化Context的Hydration错误

问题原因

Next.js的服务端渲染(SSR)机制下,服务端执行组件代码时不存在window对象,因此useState的初始值会采用默认的initialState;但客户端在Hydration阶段会从localStorage读取数据作为初始状态,导致服务端渲染的DOM内容与客户端渲染内容不匹配,触发Hydration错误。

解决方案

核心是让服务端和客户端的初始渲染状态保持一致,待客户端完成Hydration后,再从localStorage加载数据更新状态:

  • 初始化useState时直接使用默认的initialState,确保两端初始状态统一
  • 利用useEffect在客户端环境中读取localStorage并更新状态(useEffect仅在客户端执行)

修改后的完整代码

import { createContext, Dispatch, SetStateAction, useState, useEffect, ReactNode } from 'react';

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 AppStateProvider = ({ children }: Props) => {
  // 服务端与客户端初始状态统一为默认值
  const [state, setState] = useState<AppState>(initialState);

  // 客户端挂载后读取localStorage并更新状态
  useEffect(() => {
    const savedState = localStorage.getItem("state");
    if (savedState) {
      setState(JSON.parse(savedState) as AppState);
    }
  }, []);

  // 状态变化时同步到localStorage
  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;

关键说明

  • 初始useState使用默认值,保证服务端渲染内容与客户端Hydration初始内容一致,避免不匹配问题
  • 第一个useEffect依赖项为空数组,仅在客户端组件挂载后执行一次,此时读取localStorage更新状态不会干扰Hydration流程
  • 第二个useEffect监听state变化,同步数据到localStorage,保持持久化逻辑不变

内容的提问来源于stack exchange,提问作者osamu1908

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:32:43