2

I have really simple example in react. Parent component pass data to the child component throug props. Inside child component i can change this data, also new data can be passed to the child component from the parent at any time. Also on the parent i have save button. After pressing it i should show validation message if some validations did not pass. I have implemented it in such a way. From parent i pass callback to notify parent that validity of the data has changed. Inside child i perform validation in three places:

  • componentDidMount - to validate initial data
  • componentWillReceiveProps - to validate data that can be passed from the parent
  • onChange to validate entered data Any time child perform validation of data i call callback to inform parent about validity. The problem is in componentWillReceiveProps. With setState in parent this part causes infinite loop - see picture below. enter image description here Please check jsfiddle Here in console you can see that i restricted infinite loop to 10 iterations to prevent you browser from crash.

As you can see there is infinite loop - because React call componentWillReceiveProps in not too smart way - every render cycle instead of callind it only when props actually changed. I am really would like to know what is the react way to solve this issue. Should i store child state only in child ? I also tried to store child validity in parent out of state - but my coworkers said that this is not react way - why ?

1 Answer 1

2

Here's how I see your challenge:

  • you want to have your validation method in your child component, because it is specific to this type of child (e.g. a password input field). - but in react, no outside component (except grandchildren) are allowed to directly call this method.
  • you want your parent to know about the validaty of each of the children components (e.g. to determine of all the fields validate and a form submit is allowed) - so you need the result of the validation method in the parent component, and this must be state

Your co-workers are correct: react does not like you storing component-wide variables outside of state. Because such variables are completely independent from react lifecycle methods etc. and would get you in debugging hell quickly.

I would advise you to make following changes to prevent the endless loop:

  • do NOT store the validity of the child in the child state. Save the result + any message in the parent, and pass it as a props to the child. Child only renders the props.
  • implement shouldComponentUpdate(), which checks if any of the props or state variables have changed. If not return false, otherwise, return true.
  • move your call to validate() from componentWillReceiveProps to componentWillUpdate(). This ìs called after shouldComponentUpdate(). So only if props or child state have changed, will validation (and re-render) take place.
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you this is what i was looking for.
One additional note. In child component there will be two places where validaion is performed componentWillUpdate and componentDidMount - for initial validation as componentWillUpdate is not invoked during initial rendering. Final jsFiddle jsfiddle.net/t5tdqefx/4
Yeah, you can leave the validation in componentDidMount. This is only fired once, so no chance of endless loop. + no need to check if props really changed, because in initial mount there are no previous props to compare with.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.