Correct modification of state arrays in ReactJs

Problem: Correct modification of state arrays in ReactJs

I want to add an element to the end of a state array, is this the correct way to do it?

this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });

I’m concerned that modifying the array in-place with push might cause trouble – is it safe?

The alternative of making a copy of the array, and setStateing that seems wasteful.

Solutions of Correct modification of state arrays in ReactJs

Solution 1: Correct modification of state arrays in ReactJs

The React docs says:

Treat this.state as if it were immutable.

Your push will mutate the state directly and that could potentially lead to error prone code, even if you are “resetting” the state again afterwards. For example, it could lead to that some lifecycle methods like componentDidUpdate won’t trigger.

The recommended approach in later React versions is to use an updater function when modifying states to prevent race conditions:

this.setState(prevState => ({
  arrayvar: [...prevState.arrayvar, newelement]
}))

The memory “waste” is not an issue compared to the errors you might face using non-standard state modifications.

Alternative syntax for earlier React versions

You can use concat to get a clean syntax since it returns a new array:

this.setState({ 
  arrayvar: this.state.arrayvar.concat([newelement])
})

In ES6 you can use the Spread Operator:

this.setState({
  arrayvar: [...this.state.arrayvar, newelement]
})

Solution 2: Correct modification of state arrays in ReactJs

Easiest, if you are using ES6.

initialArray = [1, 2, 3];

newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]

A new array will be [1,2,3,4]

to update your state in React

this.setState({
  arrayvar:[...this.state.arrayvar, newelement]
});

Learn more about array destructuring

Solution 3: Correct modification of state arrays in ReactJs

The simplest way with ES6:

this.setState(prevState => ({
    array: [...prevState.array, newElement]
}))

Solution 4: Correct modification of state arrays in ReactJs

React may batch updates, and therefore the correct approach is to provide setState with a function that performs the update.

For the React update addon, the following will reliably work:

this.setState( state => update(state, {array: {$push: [4]}}) );

or for Concat():

this.setState( state => ({
    array: state.array.concat([4])
}));

The following shows what https://jsbin.com/mofekakuqi/7/edit?js,output as an example of what happens if you get it wrong.

The setTimeout() invocation correctly adds three items because React will not batch updates within a setTimeout callback (see https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ).

The buggy onClick will only add “Third”, but the fixed one, will add F, S and T as expected.

class List extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      array: []
    }

    setTimeout(this.addSome, 500);
  }

  addSome = () => {
      this.setState(
        update(this.state, {array: {$push: ["First"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Second"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Third"]}}));
    };

  addSomeFixed = () => {
      this.setState( state => 
        update(state, {array: {$push: ["F"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["S"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["T"]}}));
    };



  render() {

    const list = this.state.array.map((item, i) => {
      return <li key={i}>{item}</li>
    });
       console.log(this.state);

    return (
      <div className='list'>
        <button onClick={this.addSome}>add three</button>
        <button onClick={this.addSomeFixed}>add three (fixed)</button>
        <ul>
        {list}
        </ul>
      </div>
    );
  }
};


ReactDOM.render(<List />, document.getElementById('app'));

Solution 5: Correct modification of state arrays in ReactJs

If you are using functional components in React

const [cars, setCars] = useState([{
  name: 'Audi',
  type: 'sedan'
}, {
  name: 'BMW',
  type: 'sedan'
}])

...

const newCar = {
  name: 'Benz',
  type: 'sedan'
}

const updatedCarsArray = [...cars, newCar];

setCars(updatedCarsArray);

Conclusion

I hope the Correct modification of state arrays in ReactJs Solution would be useful for you to learn something new from this solution. If it helped you then don’t forget to bookmark our site for more Quiz Answers and solutions.

Leave a Reply

Your email address will not be published.

error: Content is protected !!