javascripting
javascripting

Reputation: 1153

Updating state - why creating a new copy of state when calling setState?

React docs:

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

That's clear.

class App extends React.Component {
  state = {
   data: []
  } 

the following I understand

  updateState(event) {
   const {name, value} = event.target;
   let user = this.state.user; // this is a reference, not a copy...
   user[name] = value; // 
   return this.setState({user}); // so this could replace the previous mutation
  }

this following I don't understand

  updateState(event) {
  const {name, value} = event.target;
  let user = {...this.state.user, [name]: value};
  this.setState({user});
  }

I understand (as in previous example), that I should not either only:

  1. mutate state directly without calling setState; or
  2. mutate it and then use setState afterwards.

However, why can't I just (without direct mutation) call setState without creating a new copy of state (no spread operator/Object.assign)? What would be wrong with the following:

  getData = () => {
   axios.get("example.com") ...
    this.setState({
     data:response.data
    })
  } 

Why should it be:

  getData = () => {
   axios.get("example.com") ...
    this.setState({
     data:[...data, response.data]
    })
  } 

 render (){ 
  ...
 }  
}

Upvotes: 4

Views: 4323

Answers (1)

kind user
kind user

Reputation: 41893

What would be wrong with the following:

this.setState({
   data: response.data,
});

Absolutely nothing, unless you don't want to replace the contents of this.state.data with response.data.

Why should it be:

this.setState({
   data: [...data, response.data],
});

Because with spread you are not loosing the contents of this.state.data - you are basically pushing new response into the data array.

Note: You should use callback inside setState to get access to current data from this.state.

this.setState((prevState) => ({
   data: [...prevState.data, response.data],
}));

Upvotes: 3

Related Questions