The fields in the form require me to focus on them in order to display the error message. I want the error message to appear when I click "Submit" when I haven't focused the field yet.
This is the hook (suspected to be about the later setIsTouched call):
const useInputModifed = (validationArray) => {
const [enteredValue, setEnteredValue] = useState("");
const [isTouched, setIsTouched] = useState(false);
// [{errorName:,fn:validationFn}]
let errorArray = [];
for (const errorEntry of validationArray) {
if (errorEntry.isErrorFn(enteredValue)) {
errorArray.push(errorEntry.errorName);
}
}
const hasError = errorArray.length > 0 && isTouched;
const valueChangeHandler = (event) => {
setEnteredValue(event.target.value);
};
const reset = () => {
setEnteredValue("");
setIsTouched(false);
};
console.log(errorArray, isTouched);
return {
value: enteredValue,
validationArray: errorArray,
hasError,
valueChangeHandler,
setIsTouched,
isTouched,
reset,
};
};
Here is the form handler (I used aliases for each field):
const formSubmissionHandler = (event) => {
event.preventDefault();
touchNameField(true);
touchEmailField(true);
if (nameInputHasError || emailInputHasError) {
//console logging both fields gives false even after touching
return;
}
if (!nameInputHasError && !emailInputHasError) {
resetNameInput();
resetEmailInput();
}
};
Taking the verification name field as an example, I click the submit button at the beginning.
Currently in const hasError = errorArray.length > 0 && isTouched; the array has elements but isTouched is false because I don't have focus on the field.
Then "touchNameField(true);" comes in. I tried making hasError true but it still shows false.
The setState call is asynchronous, is that the problem? If I remove the reset call it works. But I still don't understand why nameInputError etc. are false.
If you don't run it, I believe it's because
errorArrayandhasErrorare not reacting to changes. So it also depends on where you instantiate that hook. Without testing I would try the following:const useInputModifed = (validationArray) => { const [enteredValue, setEnteredValue] = useState(""); const [isTouched, setIsTouched] = useState(false); const [errorArray, setErrorArray] = useState([]); const [hasError, setHasError] = useState(false); useEffect(() => { const newErrorArray = []; for (const errorEntry of validationArray) { if (errorEntry.isErrorFn(enteredValue)) { newErrorArray.push(errorEntry.errorName); } } setErrorArray(newErrorArray); }, [validationArray, enteredValue]) useEffect(() => { setHasError(errorArray.length && isTouched); }, [errorArray, isTouched]) const valueChangeHandler = (event) => { setEnteredValue(event.target.value); }; const reset = () => { setEnteredValue(""); setIsTouched(false); }; console.log(errorArray, isTouched); return { value: enteredValue, validationArray: errorArray, hasError, valueChangeHandler, setIsTouched, isTouched, reset, }; };Again, not tested and you may need some adjustments.