自定义Next.js useLocalStorage Hook每次渲染刷新本地存储的解决方法
修复useLocalStorage Hook重复刷新本地存储的问题
你的问题出在初始状态的设置顺序上:当前代码先把initialState作为state的初始值,然后在组件挂载后才去读取本地存储并更新state,这会导致两个核心问题:
- 第一次渲染时,state是
initialState,立刻触发第二个useEffect把这个值写入本地存储,直接覆盖掉之前保存的数据; - 挂载时的
useEffect又去读取已经被覆盖的存储值,再次更新state,引发额外渲染和不必要的存储操作。
修复后的代码
import { SetStateAction, useState, useEffect } from "react"; function useLocalStorage( key: string, initialState: string ): [state: string, setState: React.Dispatch<SetStateAction<string>>] { // 函数式初始化state,仅执行一次:优先读取本地存储,无值则用initialState const [state, setState] = useState<string>(() => { const savedValue = localStorage.getItem(key); return savedValue ? JSON.parse(savedValue) : initialState || ""; }); // 仅当state或key变化时,更新本地存储 useEffect(() => { localStorage.setItem(key, JSON.stringify(state)); }, [key, state]); return [state, setState]; } export default useLocalStorage;
关键修改说明
- 函数式初始化state:
useState的函数式参数只会在组件首次挂载时执行一次,直接从本地存储获取初始值,彻底避免了先写入initialState再覆盖的问题; - 移除冗余的挂载useEffect:初始化阶段已经完成了本地存储的读取,无需再在挂载后手动触发state更新;
- 补充
key到依赖数组:确保当传入的存储键名变化时,能正确同步新的存储项,让Hook逻辑更严谨。
修改后,本地存储只会在state主动更新时才写入,不会在每次渲染时被刷新,同时初始状态会优先读取已保存的数据,不会覆盖原有内容。
内容的提问来源于stack exchange,提问作者Harshdeep Singh
相关产品推荐
相关产品推荐

