I have a form that uses immense amount of logic with auto-filling fields, depending on user input etc. In addition, I need to provide live validation while user is typing.
I used to call validators manually, depending on what fields setState() would update, but very soon that became unmaintainable. I then created a function that calls all validator methods I have, and manually invoke it every time I update the state.
Now I think about going further, and automate invoking that function. I want to implement this using
componentDidUpdate() react lifecycle method.
componentDidUpdate(prevProps, prevState) {
if (_.isEqual(prevState.data, this.state.data))
return;
this.validateAll();
}
Now, if any of the form field changed - we run full validation to be sure, that we didn't forget anything. The problem though is that lodash _.isEqual() is a costly deep-comparision operation, and componentDidUpdate() lifecycle method is invoked on any user input, so this can potentially lead to performance issues.
I decided to reduce amount of that comparisons as well as amount of validation function invocations by debouncing.
handleValidation = (prevState) => {
if (_.isEqual(prevState.data, this.state.data))
return;
this.validateAll();
};
debouncedHandleValidation = _.debounce(this.handleValidation, 200);
componentDidUpdate(prevProps, prevState) {
this.debouncedHandleValidation(prevState);
}
Here is a Live demo (calls to deep compare and validation are logged)
My question is: is it okay to handle form validation this way, or there is something I didn't take into account and my approach is bad?
Thanks.