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

useEffect无法更新localStorage数据求助:拖拽待办项后无响应

拖拽待办项后localStorage不更新的修复方案

问题根源

你在onDragEnd函数里直接操作了React状态数组的原引用——比如active = todies是直接赋值原数组的引用,再用splice修改原数组内容。React的状态更新依赖引用变化触发重渲染,当你把原数组传给setCompletedTodies时,数组引用没改变,组件不会重渲染,useEffect的依赖completedTodies也没变化,自然不会执行更新localStorage的逻辑。

修复代码

给状态数组创建新引用,用不可变的方式修改数据:

const onDragEnd = (result: DropResult) => {
  const { source, destination } = result;

  if (!destination) return;
  if (
    destination.droppableId === source.droppableId &&
    destination.index === source.index
  ) return;

  let add;
  // 复制原数组,生成新引用
  let active = [...todies];
  let completed = [...completedTodies];

  if (source.droppableId === "activeTodies") {
    add = active[source.index];
    active.splice(source.index, 1);
  } else {
    add = completed[source.index];
    completed.splice(source.index, 1);
  }

  // 复制待修改的项,避免修改原状态对象
  const updatedItem = { ...add };
  if (destination.droppableId === "activeTodies") {
    updatedItem.isDone = false;
    active.splice(destination.index, 0, updatedItem);
  } else {
    updatedItem.isDone = true;
    completed.splice(destination.index, 0, updatedItem);
  }

  setCompletedTodies(completed);
  setTodies(active);
};

关于console.log的奇怪现象

之前拖拽后console.log不触发,是因为组件没重渲染,新的log代码没执行。当你保存文件触发热重载时,组件重新渲染,此时状态已经是修改后的,所以log才会输出。

额外优化:初始加载读取localStorage

可以在初始化状态时直接从localStorage读取数据,避免页面刷新后丢失状态:

const [completedTodies, setCompletedTodies] = useState(() => {
  const savedItems = localStorage.getItem("completedTodies");
  return savedItems ? JSON.parse(savedItems) : [];
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:03:47