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

React useMemo未更新问题:Todo列表UI不随添加操作刷新

Todo列表添加项后UI不刷新的问题解决

问题场景

开发Todo列表组件时,将Todo列表的渲染逻辑通过useMemo包裹,期望仅在添加Todo项时触发UI更新,但点击添加按钮后,UI并未随之刷新。相关代码如下:

import "./styles.css";
import React from "react";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <TodoList />
    </div>
  );
}

const Todo = ({ taskName }) => {
  console.log("in here todo");
  return <div>{taskName}</div>;
};

const TodoList = () => {
  const [todoList, setTodoList] = React.useState([]);
  const [iptValue, setIptValue] = React.useState("");
  const todoWrapper = React.useMemo(() => {
    return (
      <>
        {(todoList || []).map((item) => (
          <Todo taskName={item} key={item} />
        ))}
      </>
    );
  }, [todoList]);
  return (
    <div>
      {todoWrapper}
      <input
        type="text"
        onChange={(ev) => {
          setIptValue(ev.target.value);
        }}
      />
      <button
        onClick={() => {
          const todoArr = todoList;
          todoArr.push(iptValue);
          setIptValue("");
          setTodoList(todoArr);
        }}
      >
        Add Notes
      </button>
    </div>
  );
};

问题原因

核心问题是违反了React state的不可变性原则:

  • const todoArr = todoList只是复制了原数组的引用,并非创建新数组。
  • 调用todoArr.push(iptValue)后,原state数组的内容被修改,但数组的引用并未改变。
  • 当调用setTodoList(todoArr)时,React对比前后state的引用,发现是同一个对象,因此判定state未发生变化,不会触发组件重渲染,useMemo依赖的todoList也不会更新,最终导致UI无刷新。

修复方案

需要创建新的数组来更新state,确保引用发生变化。可以通过以下几种方式实现:

方法1:使用扩展运算符创建新数组

<button
  onClick={() => {
    // 创建包含新项的新数组
    setTodoList([...todoList, iptValue]);
    setIptValue("");
  }}
>
  Add Notes
</button>

方法2:使用concat方法

<button
  onClick={() => {
    setTodoList(todoList.concat(iptValue));
    setIptValue("");
  }}
>
  Add Notes
</button>

方法3:使用slice复制数组后再push

<button
  onClick={() => {
    const todoArr = todoList.slice(); // 复制原数组得到新引用
    todoArr.push(iptValue);
    setTodoList(todoArr);
    setIptValue("");
  }}
>
  Add Notes
</button>

修复后,每次添加Todo时都会生成新的数组引用,React会检测到state变化,触发组件重渲染,useMemo也会因todoList更新而重新执行,UI就能正常显示新添加的Todo项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:23:37