在不推送es6的情况下添加行以进行反应状态 [英] add row without push in es6 for react state

查看:76
本文介绍了在不推送es6的情况下添加行以进行反应状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定自己在做正确的事,我在setState之外对变量进行了突变,对吗?还是有更优雅的方法呢?

I'm not sure I'm doing the right thing, I mutate variable outside of setState, it's fine right? or there's more elegant way to do it?

state = {
    persons: [{
      name: 'jay',
      age: 10
    }]
  }
  addRow = () => {
    const temp = this.state
    temp.persons.push({
      name: '',
      age: ''
    })
    this.setState({
      ...temp
    })
  }

应用程序演示 https://codesandbox.io/s/ppqw4wjqzq

推荐答案

在javascript中,对象分配是通过Referece进行的,因此,即使您在setState之外对变量进行了更改,只要该变量引用了state,只要您不会克隆对象.但是,如果克隆它,则将创建一个新实例,而原始实例将不受影响

In javascript, object assignment works by referece and hence Even if you mutate the variable outside of setState, it will still refer to the same reference of state as long as you do not clone your object. However if you clone it, a new instance will be created and the original one will not be affected

addRow = () => {
    const persons = [...this.state.persons] // Clone it one level deep using spread
    persons.push({
      name: '',
      age: ''
    })
    this.setState({
      persons
    })
  }

只需使用spread syntaxfunctional setState之类的

addRow = () => {
    this.setState(prevState => ({
      persons: [...prevState.persons, { name: '', age: ''}]
    }))
  }

尽管在您的示例中,这两个操作之间似乎没有什么区别,但是您提供的初始实现中存在重大缺陷.为了了解克隆和推送以及仅分配引用和推送之间的区别,您可以看到 codesandbox demo .

Although in your example there seems no difference between the two actions, there is major flaw in the initial implementation that you provided. In order to see the difference between cloning and pushing and just assigning the reference and pushing, you can see the codesandbox demo.

基本上,当您创建一个新组件时,如果将状态人员作为道具传递给该组件,并且对其原始引用进行了变异,则在componentWillReceiveProps方法中,您会看到currentPropsnextProps都是相同,因此,如果您对子组件进行了任何检查,如果人的道具发生了更改,则该组件将采取行动,那将失败.因此,不改变其参考值是非常重要的

Basically when you create a new component to which if you pass the state persons as props, and you mutate at its original reference, in the componentWillReceiveProps method, you see that the currentProps and the nextProps are both the same and hence if you have any check in the child component to take action if the persons prop changed, that would fail. Hence its extremely important to not mutate the value at its own reference

没有push和spread语法,您仍然可以通过使用concat来创建原始数组的新副本来避免突变问题

Without push and spread syntax, you can still avoid the mutation issue by using concat which create a new copy of the original array

addRow = () => {
    this.setState(prevState => ({
      persons: prevState.persons.concat([{ name: '', age: ''}])
    }))
  }

这篇关于在不推送es6的情况下添加行以进行反应状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆