【问题标题】:Why do we need to set the this variable to spread operator? Is this line needed?为什么我们需要将 this 变量设置为展开运算符?需要这条线吗?
【发布时间】:2020-05-22 19:37:41
【问题描述】:

在下面的代码中,如果 counters 已经等于状态,我不明白为什么我们需要以下行。在做什么?我可以删除该行吗?

counters[index] = { ...counters[index] };

这就是全部。

class App extends Component {
      state = {
        counters: [
          { id: 1, value: 0 },
          { id: 2, value: 0 },
          { id: 3, value: 0 },
          { id: 4, value: 0 }
        ]
      };

      handleIncrement = counter => {
        const counters = [...this.state.counters];
        const index = counters.indexOf(counter);
        counters[index] = { ...counters[index] };
        counters[index].value++;
        this.setState({ counters });
      };

【问题讨论】:

  • 这样做是为了避免变异状态。第一轮解构复制了外部数组,但是为了安全地更新嵌套对象而不发生变异,它也需要被复制。
  • 谢谢,我有点明白,但不完全明白。我记得在人们使用 .slice() 之前的一些教程中。那会解决同样的问题,所以我不需要那条线吗?也许如果我制作第一个 counters= [...this.state.counters.slice()],那么它就是完整的副本,与状态无关?我还是大雾。
  • 问题是由于对象和数组作为引用存储在变量中。复制外部数组不会破坏对内部对象的引用。我在this answer 中写了一个很长的解释,关于为什么以及如何制作嵌套副本,如果您想通读它可能会使事情更清楚(从解释开始)。
  • 阅读你的解释,想了一会儿之后,我想我已经把头绕在了它周围。所以在数组名称之前添加 ... 具有复制该数组的效果(但只是在层?),所以它第一次创建计数器的副本(所以计数器有一个唯一的引用),但它的内部仍然是指原始状态值(不是唯一的引用),因此当我设置内部值时我想不直接将其设置为 counters[index] ,因为当我们执行 counters[index].value++ 时,这最终会改变状态,因为它仍然指的是状态?我的思路清晰吗?
  • 是的,听起来你已经掌握了!

标签: reactjs


【解决方案1】:

最初的意图似乎是创建一个看起来与原始对象相同的新对象(复制所有属性),但这样做是为了避免改变原始状态。

我怀疑如果没有这条线,它似乎“工作正常”,但 React 状态旨在是不可变的。

例如见:https://flaviocopes.com/react-immutability/

【讨论】:

  • 我不明白那条线在做什么。无法绕开它......这不就像拥有一个数组[1,2,3]并说数组[0] =数组[0]吗?这有什么作用。初始化 counters 数组的第一行也不只是复制状态中的所有内容,因此在最后一行之前不会改变状态?
猜你喜欢
  • 1970-01-01
  • 2011-04-14
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 2022-01-14
  • 2011-07-12
相关资源
最近更新 更多