Reputation: 2211
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 datacomponentWillReceiveProps
- to validate data that can be passed from the parentonChange
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.
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 ?
Upvotes: 2
Views: 3412
Reputation: 14101
Here's how I see your challenge:
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:
shouldComponentUpdate()
, which checks if any of the props or state variables have changed. If not return false
, otherwise, return true
.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.Upvotes: 2