I want the useEffect to occur multiple times. For example in the below example, everything works correctly the first time round.
If the input field is empty, and you click on ‘Next’, the focus then shifts to another button. When you click this button, the focus then shifts to the incomplete question. However this only works on the first render. How do I get it to work so that the useEffect occurs each time the button is clicked?
https://codepen.io/theinteractivedom/pen/ZExpqBy
const Summary = () => {
const [hasErrors, setHasErrors] = useState(false);
const [message, setMessage] = useState("");
const goToQuestionButton = useRef();
const inputRef = useRef();
const handleClick = () => {
if (message.trim().length !== 0) {
console.log("input value is NOT empty");
} else {
setHasErrors(true);
}
};
const handleClickTwo = () => {
inputRef.current.focus();
};
const handleChange = (event) => {
setMessage(event.target.value);
};
useEffect(() => {
if (hasErrors === true) {
goToQuestionButton.current.focus();
}
}, [hasErrors]);
return (
<div className='questions'>
<p>What is your name?</p>
<input
onChange={handleChange}
ref={inputRef}
id="firstName"
name="firstName"
></input>
<button onClick={handleClickTwo} ref={goToQuestionButton}>
Go to incomplete question
</button>
<button onClick={handleClick}>Next</button>
</div>
);
};
>Solution :
useEffect will trigger any time the value of hasErrors changes. You never reset the hasErrors value after the input is focused.
useEffect(() => {
if (hasErrors === true) {
goToQuestionButton.current.focus();
setHasErrors(false);
}
}, [hasErrors]);
Setting hasErrors to false after focusing the question will reset everything and allow it to be triggered again the next time hasErrors is set to true.