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

Next.js中从localStorage取数时如何避免无限循环?

解决Next.js中useEffect读取localStorage的无限循环与数据不更新问题

问题根源

  • 空依赖数组[]:useEffect仅在组件挂载时执行一次,新增数据后不会主动重新读取localStorage,必须刷新页面才能获取新数据。
  • 依赖[data]:每次data状态更新都会触发useEffect,而useEffect里的setData又会再次修改data,形成无限循环。

正确解决方案

方案1:提交时同步更新状态与localStorage

直接在提交函数里同时更新状态和localStorage,无需依赖useEffect重复读取,这是最简洁的方式:

const LocalStorage = () => {
  const [data, setData] = useState([]);
  const [id, setId] = useState("");
  const [name, setName] = useState("");
  const [city, setCity] = useState("");

  // 组件挂载时读取初始数据
  useEffect(() => {
    const fetchedData = localStorage.getItem("user");
    if (fetchedData) {
      setData(JSON.parse(fetchedData));
    }
  }, []);

  const handleSubmit = () => {
    // 构造新数据
    const newUser = { id, name, city };
    const updatedData = [...data, newUser];
    
    // 同步更新localStorage和状态
    localStorage.setItem("user", JSON.stringify(updatedData));
    setData(updatedData);
    
    // 清空表单
    setId("");
    setName("");
    setCity("");
  };

  // 省略渲染逻辑...
};

方案2:监听localStorage变化(跨页面场景)

如果需要监听其他页面修改localStorage的情况,可以添加storage事件监听,注意该事件仅在同源的其他标签页/窗口触发:

useEffect(() => {
  // 读取初始数据
  const initData = localStorage.getItem("user");
  if (initData) setData(JSON.parse(initData));

  // 监听storage变化
  const handleStorageChange = (e) => {
    if (e.key === "user") {
      setData(JSON.parse(e.newValue));
    }
  };

  window.addEventListener("storage", handleStorageChange);
  return () => window.removeEventListener("storage", handleStorageChange);
}, []);

关键注意点

  • 避免在依赖包含data的useEffect里调用setData,这必然导致无限循环。
  • 操作localStorage时记得判断getItem的返回值,避免JSON.parse(null)报错。
  • 表单状态初始化建议设为空字符串"",而非undefined,避免渲染时出现异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:15:20