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

React类组件状态处理逻辑迁移为Hooks写法报错如何解决?

问题原因和修复方案

核心错误点:setTasks回调的参数取值错误

你在类组件中的state是外层包含tasks属性的对象,所以类组件setState回调拿到的prevState是整个状态对象,可以正确解构出tasks。
但在Hooks写法中,你用useState存的直接就是tasks分组对象本身,没有外层包装。你写的setTasks(({ tasks }) => {})相当于从prevState里解构tasks属性,而prevState本身就是你要的tasks集合,自然拿不到值,tasks变成undefined,后续调用tasks[item.status]就触发了类型错误。

额外隐患:直接修改原state对象

你之前的写法是直接对原state数组执行push操作,属于直接修改state的突变操作,不符合React状态不可变的更新原则,容易引发渲染异常,类组件写法虽然暂时运行正常,但也存在相同隐患。

修正后的代码

const [tasks, setTasks] = useState({
  workingProgress: [],
  toDo: [],
  done: [],
});
const history = useHistory();

useEffect(() => {
  TasksAPI.getAll().then((res) => {
    setTasks(prevTasks => {
      // 先拷贝原对象,避免修改原state
      const newTasks = {
        workingProgress: [...prevTasks.workingProgress],
        toDo: [...prevTasks.toDo],
        done: [...prevTasks.done],
      };
      res.forEach((item) => {
        if (newTasks[item.status]) {
          newTasks[item.status].push(item);
        }
      });
      return newTasks;
    });
  });
}, []);

你也可以用更简洁的分组写法实现同样效果:

useEffect(() => {
  TasksAPI.getAll().then((res) => {
    setTasks(prev => {
      const result = { ...prev };
      res.forEach(item => {
        if(result[item.status]) {
          result[item.status] = [...result[item.status], item];
        }
      });
      return result;
    })
  })
}, [])

渲染逻辑说明

你的现有渲染代码不需要修改,Hooks中定义的tasks本身就是你要遍历的分组对象,和原来类组件中this.state.tasks结构完全一致。

内容的提问来源于stack exchange,提问作者Iván

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:36:04