Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do not mutate state directly, Use setState() react/no-direct-mutation-state in React JS

Tags:

reactjs

eslint

<input
  defaultValue={this.props.str.name}
  ref={(input) => { this.state.name = input; }}
  name="name"
  type="text"
  className="form-control"
  onChange={this.handleInputChange}
/> 

handleInputChange(event) {
  this.setState({
    [event.target.name]: event.target.value
  });
}

if(this.state.name.value === "") {
  this.msg.show('Required fields can not be empty', {
    time: 2000,
    type: 'info',
    icon: <img src="img/avatars/info.png" role="presentation"/>
  });
}

I'm trying to set the default value like that and wanted to access it as well. I did like this and accessed the value with this.state.name.value but the thing is its working but showing the warning as

Do not mutate state directly, Use setState() react/no-direct-mutation-state .

like image 807
Piyush Avatar asked Apr 29 '17 04:04

Piyush


People also ask

Why we should not mutate state directly?

So, when you mutate the state directly and call setState() with an empty object. The previous state will be polluted with your mutation. Due to which, the shallow compare and merge of two states will be disturbed or won't happen, because you'll have only one state now.

Why do you need to use setState () to update state in React?

Always use the setState() method to change the state object, since it will ensure that the component knows it's been updated and calls the render() method.

Can we mutate 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 .

Why we should not update the state directly and use setState?

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. state immediately.


1 Answers

Getting "Do not mutate state directly, Use setState()", Why?

Because, you are mutating the state value inside ref callback method to store the node ref, Here:

this.state.name = input;

Solution:

Don't use state variable to store the reference, You can directly store them in component instance because that will not change with time.

As per DOC:

The state contains data specific to this component that may change over time. The state is user-defined, and it should be a plain JavaScript object.

If you don’t use it in render(), it shouldn’t be in the state. For example, you can put timer IDs directly on the instance.

Since you are using controlled input element, ref is not required. Directly use this.state.name with input element value property and this.state.name to access the value.

Use this:

<input
    value={this.state.name || ''}
    name="name"
    type="text"
    className="form-control"
    onChange={this.handleInputChange} 
/>

If you wanted to use ref then store the ref directly on instance, remove value property and you can remove the onChange event also, Use it like this:

<input
    ref={el => this.el = el}
    defaultValue={this.props.str.name}
    name="name"
    type="text"
    className="form-control"
/> 

Now use this ref to access the value like this:

this.el.value

like image 85
Mayank Shukla Avatar answered Sep 28 '22 13:09

Mayank Shukla