React - Changing the state without using setState: Must avoid it?

后端 未结 4 1992
轮回少年
轮回少年 2020-12-19 02:55

My code works, but I have a best practice question: I have an array of objects in the state, and a user interaction will change a value of one object at a time. As far a

相关标签:
4条回答
  • 2020-12-19 03:03

    If I understood your question right, you have an array of objects and when a property of a single object in array changes,

    1. Create a deep clone of the array and pass to setState
    2. Create a shallow clone and pass to setState

    I just checked with the redux sample todo app and in case of a single property of an object changes you've to create a fresh copy of that single object not the entire array. I recommend you to read about redux and if possible use to manage the state of your app.

    0 讨论(0)
  • 2020-12-19 03:16

    Muting the state directly breaks the primary principle of React's data flow (which is made to be unidirectional), making your app very fragile and basically ignoring the whole component lifecycle.

    So, while nothing really stops you from mutating the component state without setState({}), you would have to avoid that at all costs if you want to really take advantage of React, otherwise you would be leapfrogging one of the library's core functionalities.

    0 讨论(0)
  • 2020-12-19 03:23

    Personally I don't always follow the rule, if you really understand what you are trying to do then I don't think it's a problem.

    var data = this.state.data.slice(0);
    data[index].is_collected = !data[index].is_collected;
    this.setState({data: data});
    

    In this case, mutating state and calling the setState again like this is fine

    this.state.data[index].is_collected = !this.state.data[index].is_collected;
    this.setState({data: this.state.data});
    

    The reason you should avoid mutating your state is that if you have a reference to this.state.data, and calling setState multiple times, you may lose your data:

    const myData = this.state.data
    myData[0] = 'foo'
    this.setState({ data: myData })
    // do something...
    // ...
    const someNewData = someFunc()
    this.setState({ data: someNewData })
    
    myData[1] = 'bar' // myData is still referencing to the old state
    this.setState({ data: myData }) // you lose everything of `someNewData`
    

    If you really concerned about this, just go for immutable.js

    0 讨论(0)
  • 2020-12-19 03:26

    If you want follow react best practices, you should do shallow copy of all your array, when you change any property. Please look into "immutable" library implementation.

    But, from my experience, and from my opinion, setState method should be called if you have "shouldCompomenentUpdate" implementations. If you think, that your shallow copy will be consume much more resources, then react virtual dom checks, you can do this:

    this.state.data[0].property = !this.state.data[0].property;
    this.forceUpdate();
    
    0 讨论(0)
提交回复
热议问题