Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: Best way to check state values and update render based on state?

So, I have a form with multiple inputs that update state onChange.

What I want to happen, is let the user change the values and when they change, update the the form's state to save these changes. My code using ES6 classes:

super(props);
 this.state = {
   post: this.props.content // this is an object {title: '', description: ''}
 }

 // I have all the methods below this.method = this.method.bind(this) up here.
}

handleTitle(title) { // gets title from input onChange event
  let post = update(this.state.post, {title: {$set: title}}); // using import update from 'immutability-helper' for changing object
  this.setState({ post });
  this.checkPostApproval();
} // this all works, post is updated. I have the same code for description.

checkPostApproval() {
  // here I want to check the post values and make sure they are valid.
  // and either allow or deny submission. 
  if (this.state.post['title'] && this.state.post['description']) {
    this.setState({isApproved: true});
  } else {
    this.setState({isApproved: false});
  }
} 

The problem:

When users set the title and then the description, isApproved switches to true (what I want). However, if the user then changes the title to "", the approval remains true (not what I want). If the user then starts typing in the description (the approval switches to false). I believe this has to do with the component lifecycle and when the state is being set, but I'm not sure.

I don't mind using jQuery to check for validation, but I was hoping to just check the values after the inputs change and then update the post using methods and props.

What is the best practices approach to updating an object in state and then validating it using onChange event handlers in various input fields?

Ultimately, I would like isApproved to be false, if there are any invalid inputs.

like image 474
Daltron Avatar asked May 14 '17 22:05

Daltron


1 Answers

Please run the post approval test in setState callback (second parameter). As you already noticed - the setState method is asynchronous and component state isn't updated immediately.

this.setState({post}, this.checkPostApproval)

Please see this note from React's documentation about setState:

setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

like image 134
Przemysław Zalewski Avatar answered Sep 28 '22 07:09

Przemysław Zalewski