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

React类组件中不Mutate原数组删除State数组元素的实现方法

嘿,作为React新手碰到状态更新尤其是数组操作的问题太正常啦!我来帮你搞定这个删除todos元素的需求,而且保证不修改原数组~

首先,先看看你当前的todos结构:每个元素是一个只有单个键值对的对象,比如{0: "Wake up"}。这种结构虽然能工作,但操作起来有点麻烦,我先按你现有的结构给出解决方案,之后再建议更友好的结构优化。

方案1:根据键删除指定元素(比如删除键为1的元素)

我们可以用数组的filter方法,它会返回一个新数组,完全不会修改原数组,完美符合React的状态更新要求:

// 定义要删除的键
const keyToDelete = 1;

// 生成不包含目标元素的新数组
const newTodos = this.state.todos.filter(todo => {
  // 获取当前todo对象的唯一键(因为每个对象只有一个键)
  const todoKey = Object.keys(todo)[0];
  // 把字符串类型的键转成数字,和目标键对比
  return Number(todoKey) !== keyToDelete;
});

// 更新state
this.setState({ todos: newTodos });

方案2:根据文本内容删除指定元素(比如删除"Have breakfast")

如果你不知道键,只知道要删除的文本内容,同样用filter:

const textToDelete = "Have breakfast";

const newTodos = this.state.todos.filter(todo => {
  // 获取当前todo的文本值
  const todoText = Object.values(todo)[0];
  return todoText !== textToDelete;
});

this.setState({ todos: newTodos });

更推荐的todos结构优化

其实上面的写法有点繁琐,是因为当前的todos结构不够直观。推荐你把每个todo改成包含id和text的对象,这样后续操作会方便很多:

// 初始化state时改成这样
this.state = {
  todos: [
    { id: 0, text: "Wake up" },
    { id: 1, text: "Have breakfast" },
    { id: 2, text: "Have lunch" }
  ]
};

此时根据id删除元素就简单多了:

const idToDelete = 1;

// 用filter生成新数组
const newTodos = this.state.todos.filter(todo => todo.id !== idToDelete);

// 更新state
this.setState({ todos: newTodos });

额外小提示:使用函数式setState更安全

如果你更新状态的时候依赖于之前的state(比如删除元素肯定依赖旧的todos数组),推荐使用函数式的setState,因为React的状态更新是异步的,这种方式能确保你拿到最新的状态:

const idToDelete = 1;

this.setState(prevState => ({
  todos: prevState.todos.filter(todo => todo.id !== idToDelete)
}));

总结一下,核心就是永远不要直接修改state里的原数组,而是用filter(或者map、concat这些返回新数组的方法)生成新数组,再通过setState更新就好啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:22:42