Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the preferred way to mutate a React state?

Let's say I have a list of plain objects in my this.state.list that I can then use to render a list of children. What then is the right way to insert object into this.state.list?

Below is the only way I think it will work because you can not mutate the this.state directly as mentioned in the doc.

this._list.push(newObject):
this.setState({list: this._list});

This seems ugly to me. Is there a better way?

like image 689
Khoi Avatar asked May 31 '14 04:05

Khoi


People also ask

How do you mutate a state in React?

In React, the state is immutable. In simple terms it means that you should not modify it directly. Instead a new object should be created to set the state using setState .

What is the best way to manage state in React?

Local state is perhaps the easiest kind of state to manage in React, considering there are so many tools built into the core React library for managing it. useState is the first tool you should reach for to manage state in your components. It can take accept any valid data value, including primitive and object values.

Why shouldn't we mutate the state in React?

One should never update the state directly because of the following reasons: If you update it directly, calling the setState() afterward may just replace the update you made. When you directly update the state, it does not change this.

What is mutate in React?

To run a mutation, you first call useMutation within a React component and pass it a GraphQL string that represents the mutation. When your component renders, useMutation returns a tuple that includes: A mutate function that you can call at any time to execute the mutation.


4 Answers

concat returns a new array, so you can do

this.setState({list: this.state.list.concat([newObject])});

another alternative is React's immutability helper

  var newState = React.addons.update(this.state, {
      list : {
        $push : [newObject]
      }
  });

  this.setState(newState);
like image 200
Heap Avatar answered Sep 22 '22 23:09

Heap


setState() can be called with a function as a parameter:

this.setState((state) => ({ list: state.list.concat(newObj) }))

or in ES5:

this.setState(function(state) {
  return {
   list: state.list.concat(newObj)
  }
})
like image 33
Nyalab Avatar answered Sep 22 '22 23:09

Nyalab


Update 2016

With ES6 you can use:

this.setState({ list: [...this.state.list, ...newObject] });
like image 32
Ashish Chaudhary Avatar answered Sep 23 '22 23:09

Ashish Chaudhary


From the react docs (https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous):

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

So you should do this instead:

this.setState((prevState) => ({
  contacts: prevState.contacts.concat([contact])
}));
like image 25
jcgzzc Avatar answered Sep 24 '22 23:09

jcgzzc