【问题标题】:React: why is that mutating the state leaves the component in such a weird stateReact:为什么改变状态会使组件处于如此奇怪的状态
【发布时间】:2021-11-01 06:48:51
【问题描述】:

首先,让我先发制人地解决这个问题,我知道我们不应该改变状态。我只是想探索如果我们直接改变状态到底会出什么问题。

在这里,我构建了一个简单的待办事项应用程序。待办事项存储在一个数组中。例如 [{id: 0, name: 'foo'}, {id: 1, name: 'bar'}]

要从列表中删除一个待办事项,我认为我们应该做什么,即不可变的方法是从列表中过滤掉该待办事项并返回一个新列表的副本。 即

setTodos((prevTodos) => prevTodos.filter((todo) => todo.id !== id));

但我在想,这可能会很慢,因为它是一个 O(n) 过程。如果我们知道列表中每个待办事项的索引,我们可以通过持续时间查找从列表中找到该项目并将其设置为 null 或其他内容。

实现这一点的一种方法是使用一个从0 开始的count 变量,我们将其用作每个待办事项的id,并且每次添加新的待办事项时都会增加计数。在这种情况下,id 将等于与待办事项在列表中的位置相对应的数字索引。我们只需获取该 id 并直接更新列表。

todos[id] = null;

但是,这会使组件处于一种奇怪的状态,每次我删除一项时,列表实际上都会添加一个待办事项。

例如,之前我们有[{id: 0, name:'foo'}] 在我们执行todos[0] =null 之后,我们将得到[null, {id: 1, name:''}]

这是一个现场演示,您可以使用https://codesandbox.io/s/react-todo-mutate-e0zj3?file=/src/App.js 玩游戏

有人能指出这个错误究竟是怎么发生的吗?

我再次知道改变状态不是正确的方法,但我只是想更深入地了解 React,所以我做了这个小实验。

【问题讨论】:

  • 既然 Id 是 1,显然它正在运行您的 addTodo 代码,对吗?我的意思是没有其他方法可以获取下一个 ID。
  • O(n) 很慢?这简直是​​闪电般的速度。

标签: javascript reactjs


【解决方案1】:

这不是反应行为。按钮有隐含的type="submit"。因此,单击删除按钮您正在提交表单(添加新的待办事项,并在数组中的某个索引处设置 null)。

【讨论】:

    猜你喜欢
    • 2020-05-24
    • 1970-01-01
    • 2019-05-15
    • 2017-04-06
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多