Next.js中操作localStorage配合useEffect出现无限循环问题咨询
问题根因
- 无限循环的直接原因是
useEffect配置了meetings作为依赖项,但回调内部执行了setMeetings更新该状态:每次状态更新会触发组件重渲染,进而重新执行effect回调,形成死循环。 - 现有逻辑还存在其他问题:
- Next.js服务端渲染阶段没有
window对象,直接调用localStorage会抛出未定义错误 - 数据赋值逻辑错误:本地存储是空数组时,
[...meetings, meetingsInLocalStorage]会生成嵌套数组,不符合你预期的一维数组结构 - 重复调用
localStorage.getItem和JSON.parse,存在冗余
- Next.js服务端渲染阶段没有
修复方案
你当前的场景不需要使用useCallback/useMemo/useRef,调整依赖项和逻辑即可:
- 所有
localStorage操作都添加客户端环境判断,规避SSR报错 - 初始化读取本地存储的逻辑,依赖项设置为空数组
[],仅在客户端组件首次挂载后执行一次 - 简化判断逻辑,修正数据赋值规则
修正后代码
const [meetings, setMeetings] = useState([]) // 仅执行一次的初始化读取逻辑 useEffect(() => { // 服务端环境直接返回,不执行本地存储操作 if (typeof window === 'undefined') return const rawMeetings = localStorage.getItem('meetings') // 覆盖空值、空字符串、null三种情况 if (!rawMeetings) { localStorage.setItem('meetings', JSON.stringify([])) setMeetings([]) return } const parsedMeetings = JSON.parse(rawMeetings) setMeetings(parsedMeetings) }, []) // 可选:如果需要meetings变化时自动同步到本地存储,单独加这个effect useEffect(() => { if (typeof window === 'undefined') return localStorage.setItem('meetings', JSON.stringify(meetings)) }, [meetings])
额外说明
你提到的三个Hook的适用场景和当前问题不匹配:
useCallback/useMemo用于缓存函数或计算结果,解决不必要的重渲染开销,和当前的循环问题无关useRef用于存储不触发组件渲染的可变值,当前初始化场景不需要使用
内容的提问来源于stack exchange,提问作者GabVlado
相关产品推荐
相关产品推荐

