React中如何将localStorage值同步至state?明暗模式初始化异常求助
解决明暗模式状态与localStorage同步问题
问题根源
- 初始state未读取localStorage:你把
dark初始值固定为false,后续用useEffect修正时逻辑混乱,还调用了onClick导致状态反向切换,反而搞乱了初始值。 - localStorage存储时机错误:
onClick里调用setDark是异步的,此时dark还是旧值,存到localStorage的不是最新状态。 - 直接操作DOM不符合React范式:手动修改
body类名容易和React状态不同步,应该用状态驱动DOM变化。
修正后的代码
function Mode() { // 初始化时直接从localStorage读取,没有值则默认false const [dark, setDark] = useState(() => { const saved = localStorage.getItem("dark"); return saved !== null ? JSON.parse(saved) : false; }); // 切换模式的逻辑只负责修改状态 const onClick = () => { setDark(prev => !prev); }; // 监听dark状态变化,同步更新localStorage和body类名 useEffect(() => { localStorage.setItem("dark", JSON.stringify(dark)); if (dark) { document.body.classList.add("dark"); } else { document.body.classList.remove("dark"); } }, [dark]); return ( <div onClick={onClick} className="mode"> {dark ? <Light /> : <Dark />} </div> ); }
关键优化点
- 初始值从localStorage读取:用
useState的函数式初始化,只在组件挂载时读取一次localStorage,避免每次渲染都读取。 - 状态切换用函数式更新:
setDark(prev => !prev)确保拿到最新的状态值,避免异步更新导致的错误。 - 状态驱动DOM变化:通过
useEffect监听dark变化,统一处理localStorage存储和body类名修改,保证状态和DOM同步。
内容的提问来源于stack exchange,提问作者tices
相关产品推荐
相关产品推荐

