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

为何我的Todo List应用中TaskList组件未重新渲染?

问题分析与解决方案

核心问题是你在组件函数内部直接声明了taskList,每次组件渲染时这个变量都会被重新初始化,导致MobX的observer无法持续追踪它的变化,组件也不会因为它的更新触发重新渲染。

解决步骤:

  1. 持久化observable对象:用useRef保存taskList,确保组件整个生命周期内引用不变,避免每次渲染重置状态。
  2. 简化action调用:makeAutoObservable已经自动将对象的修改操作包装为action,不需要手动用action()包裹。
  3. 添加React列表key:给map生成的元素添加唯一key,符合React规范。

修改后的完整代码:

interface Task {
  task: string;
}
export default observer(function TaskList() {
  const [update, setUpdate] = useState<string>('');
  // 用useRef持久化observable对象
  const taskListRef = useRef(makeAutoObservable({ tasks: [] as Task[] }));
  const taskList = taskListRef.current;

  useEffect(() => {
    fetchData();
  }, []);

  const fetchData = async () => {
    try {
      const response: any = await axios.get('http://localhost:5000/data');
      // 直接修改即可,makeAutoObservable已自动处理action
      taskList.tasks.push(...response.data.recordset);
    } catch (error) {
      console.error(error);
    }
  };

  const onChangeValue = (e: any) => {
    setUpdate(e.target.value);
  };

  return (
    <div>
      <p>
        update input <input onChange={onChangeValue} value={update} />
      </p>
      {taskList.tasks.map((value, key) => (
        <div key={key}>
          <div>
            <p>
              {value.task}
              <DeleteTask value={value} taskList={taskList} />
              <UpdateTask
                value={update}
                current={value}
                taskList={taskList}
              />
            </p>
          </div>
        </div>
      ))}
    </div>
  );
});

补充说明:

  • useRef的作用是在组件渲染周期中保持引用的稳定性,这样MobX的响应系统能正确关联到同一个observable对象,当taskList.tasks变化时,observer组件会自动重新渲染。
  • 如果任务列表需要在多个组件间共享,也可以将taskList提取为组件外部的全局MobX store,效果类似但更适合跨组件状态管理。

内容的提问来源于stack exchange,提问作者Chan Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:30:50