What the Difference of This.State and This.Setstate in Reactjs

What the difference of this.state and this.setstate in ReactJS?

Here's what the React docs say:

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.
setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate().

If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate(), calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders.

It's always sensible to use APIs in the way they were designed. If the docs say don't mutate your state, then you'd better not mutate your state.

Whilst setState() might be technically asynchronous, it's certainly not slow in any noticeable way. The component's render() function will be called in pretty short order.

One drawback of setting state directly is that React's lifecycle methods - shouldComponentUpdate(), componentWillUpdate(), componentDidUpdate() - depend on state transitions being called with setState(). If you change the state directly and call setState() with an empty object, you can no longer implement those methods.

Another is that it's just bad programming style. You're doing in two statements what you could be doing in one.

Moreover, there's no actual benefit here. In both cases, render() is not going to be triggered until after setState() (or forceUpdate()) is called.

You claim a need to do this without actually explaining what that need is. Perhaps you'd like to detail your problem a little more. There's probably a better solution.

It's best to work with the framework rather than against it.

UPDATE

From the comments below:

The need is that I want use the changed hasSubmit in below.

OK, I understand now. If you need to immediately use the future state property, your best bet is just to store it in a local variable.

const hasSubmit = false;

this.setState({
hasSubmit: hasSubmit
});

if (hasSubmit) {
// Code that will use `hasSubmit` ...

Why to avoid this.setState(this.state)?

setState doesn't care if the object you set has the same reference as the current state. render() will be called either way.

Immutability is useful only for shallow checking (using === to compare before and after) in the context of optimization with the shouldComponentUpdate lifecycle method, which by default returns true.

What is the difference between state and props in React?

Props and state are related. The state of one component will often become the props of a child component. Props are passed to the child within the render method of the parent as the second argument to React.createElement() or, if you're using JSX, the more familiar tag attributes.

<MyChild name={this.state.childsName} />

The parent's state value of childsName becomes the child's this.props.name. From the child's perspective, the name prop is immutable. If it needs to be changed, the parent should just change its internal state:

this.setState({ childsName: 'New name' });

and React will propagate it to the child for you. A natural follow-on question is: what if the child needs to change its name prop? This is usually done through child events and parent callbacks. The child might expose an event called, for example, onNameChanged. The parent would then subscribe to the event by passing a callback handler.

<MyChild name={this.state.childsName} onNameChanged={this.handleName} />

The child would pass its requested new name as an argument to the event callback by calling, e.g., this.props.onNameChanged('New name'), and the parent would use the name in the event handler to update its state.

handleName: function(newName) {
this.setState({ childsName: newName });
}

Performance comparison this.setState(this.state) vs this.setState({})

If you want to call setState only once, you can do it like this:

componentWillReceiveProps(newProps) {
// Copy the state instead of mutating this.state directly.
const state = { ...this.state };

if (newProps.listOne) {
state.listOne = newProps.listOne;
}

if (newProps.listTwo) {
state.listTwo = newProps.listTwo;
}

this.setState(state);
}

You can further improve here by using truly immutable data structures by means of libraries such as Immuable.js.

However, manually batching updates like this isn't necessary from a performance point of view; React internally batches these updates already since this is a lifecycle hook. It might make sense if you want to use the callback from setState, though.

setState vs replaceState in React.js

With setState the current and previous states are merged. With replaceState, it throws out the current state, and replaces it with only what you provide. Usually setState is used unless you really need to remove keys for some reason; but setting them to false/null is usually a more explicit tactic.

While it's possible it could change; replaceState currently uses the object passed as the state, i.e. replaceState(x), and once it's set this.state === x. This is a little lighter than setState, so it could be used as an optimization if thousands of components are setting their states frequently.

I asserted this with this test case.


If your current state is {a: 1}, and you call this.setState({b: 2}); when the state is applied, it will be {a: 1, b: 2}. If you called this.replaceState({b: 2}) your state would be {b: 2}.

Side note: State isn't set instantly, so don't do this.setState({b: 1}); console.log(this.state) when testing.



Related Topics



Leave a reply



Submit