add row without push in es6 for react state

前端 未结 2 1334
别跟我提以往
别跟我提以往 2021-01-25 08:32

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:          


        
相关标签:
2条回答
  • 2021-01-25 09:10

    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
        })
      }
    

    The above can be done using simply spread syntax and functional setState like

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

    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.

    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

    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: ''}])
        }))
      }
    
    0 讨论(0)
  • 2021-01-25 09:19

    In my opinion, more elegant way would be to use functional setState:

    const newPerson = { name: '', age: -1 };
    this.setState(prevState => ({ persons: [...prevState.persons, newPerson] })
    
    0 讨论(0)
提交回复
热议问题