Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to remove key from react state

Tags:

reactjs

state

I am using the state of a react (v0.14) view to hold key value pairs of unsaved user ids and user objects. For example:

onChange = (user, field) => {
  return (event) => {
    let newUser = _.clone(this.state[user.uuid] || user);
    _.assign(newUser, {[field]: event.target.value});
    this.setState({
      [user.uuid]: newUser
    });
  }
}

render() {
   let usersJsx = users.map((user, i) => {
     return <div key={i}>
       <input type="text" value={user.name}
         onChange={this.onChange(user, 'name')}/>
     </div>;
   });

   let numberUnsavedUsers = _.keys(this.state).length;

   // ... etc
}

This all works perfectly until I come to the save method:

persistUsers = (event) => {

  let unsavedUsers = _.toArray(this.state);
  updateUsers(unsavedUsers, {
    onSuccessCb: (savedUsers) => {

      // Would prefer to remove these two lines and replace
      // with `this.setState({});` but this doesn't work... i.e.
      // the state is left untouched rather than being
      // replaced with `{}`.  This makes sense.  I guess I was hoping
      // someone might point me towards a this.replaceState()
      // alternative.
      this.setState({nothing: true}); // triggers a state change event.
      this.state = {};  // wipes out the state.
    }    
  });
}

I've searched around but only found people modifying nested objects or arrays and not top level key values.

like image 518
AJP Avatar asked Apr 28 '16 00:04

AJP


1 Answers

You need to use replaceState instead of setState

Update: replaceState is being deprecated. You should follow the recommendation and use setState with null values.

Recommendation:

You should name the data and use setState so you can more easily work with it.

instead of:

//bad
this.setState({
  [user.uuid]: newUser
});

use:

//good
this.setState({
 newUser: {uuid: user.uuid}
})

If your state was {unsavedUsers: {userData}} instead of {userData} then you could easily setState({unsavedUsers: {}}) without introducing replaceState.

replaceState is an anti-pattern because it is uncommonly used.

Original Answer:

Like setState() but deletes any pre-existing state keys that are not in the newState object.

Documentation

this.replaceState({}) will remove all the objects.

like image 183
Blair Anderson Avatar answered Oct 13 '22 00:10

Blair Anderson