Reputation: 323
I have Form and Input components. Form contains Input as children. whenever the form submits I am sending an incremented value to child Input component. In the Input component, I have a listener (useEffect) on that incremented value to validate the input. after validating the input I am calling a function onValidation(isValid) which is received from parent as props. and trying to update the parent component with validation results. But, When the form is submitting all the child components are calling the onValidation method same time and parent setting the state immediately. because the react setstate won't affect immediately the validation data is not setting correctly in parent. Here is the code.
Is there any way to solve this problem? If not, what is the best pattern for these use cases?
function Form() {
const [validations,setValidations] = useState({})
function onValidation(isValid,key) {
setValidations({...validations,...{[key]:isValid}});
}
function onSubmit(){
//Here the validations object not containing all the input fields data.
// because while doing setValidation some data is missing
let isValid = Object.keys(validations).reduce((prev,curKey)=>{return (prev && validations[curKey]) },true);
if(isValid) {
window.alert("The form is valid");
}else {
window.alert("The form is not valid");
}
}
return (
<form onSubmit={onSubmit}>
<Input name="first" onValidation={onValidation}/>
<Input name="second" onValidation={onValidation}/>
<Input name="third" onValidation={onValidation}/>
<Input name="fourth" onValidation={onValidation}/>
</form>
)
}
function Input(value,name,onValidation) {
function validate(e) {
var val = e.target.value;
if(val){
onValidation(true,name)
}else {
onValidation(false,name)
}
}
return (
<input type="text" onChange={validate} value={value}>
)
}
Upvotes: 0
Views: 1212
Reputation: 5264
just add initial state to validations
.
https://codesandbox.io/s/cocky-snowflake-g2rr5?file=/src/App.js
your initial keys is empty object so none of the props are false therefore validation is ok
I now understand what's annoying you. please read this answer.
Upvotes: 0
Reputation: 323
After little digging found a solution for this problem.
when setting the validations with setValidations, instead of setting it directly we have to set it with a callback function. with this way the state is setting properly. updated the code sandbox accordingly.
setValidations((validations) => {
return { ...validations, ...{ [key]: isValid } };
});
https://codesandbox.io/s/serene-hofstadter-4nqr3?file=/src/App.js
Upvotes: 1