I have a useEffect hook that tracks the state variable values. I want to call the hook whenever values is changed. However, there is one case where I don’t want to call the useEffect hook and that is when I am calling the function handleReset(). I attempt to set a flag resetting to true while in the function and then setting it to false after the function completes (the idea is to enter the useEffect hook but then skip it via if(resetting.current)… however, the code never enters the if statement and does not skip if resetting.curent == true.
How can I properly skip the call to useEffect if we are setting the dependency states via the handleReset() function?
export const Component: React.FC<Props> = ({}) => {
const resetting = React.useRef(false);
const [values, setValues] = React.useState(getDefaultValues());
React.useEffect(() => {
if (resetting.current) {
// skip useEffect if we are in handleReset()
return;
}
if (someCondition) {
// do stuff
}
}, [values, resetting.current]);
const handleReset = () => {
resetting.current = true;
setValues(getDefaultValues());
resetting.current = false;
};
return ();
};
>Solution :
Setting the state is an async operation. When you call handleReset
const handleReset = () => {
resetting.current = true;
setValues(getDefaultValues());
resetting.current = false; // <- this would happen before the useEffect is triggered
};
the resetting.current would be changed to false before updating the state, whoch would cause a re-render, and trigger the useEffect.
Instead, change resetting.current to false in the useEffect if resetting.current is true:
export const Component: React.FC < Props > = ({}) => {
const resetting = React.useRef(false);
const [values, setValues] = React.useState(getDefaultValues());
React.useEffect(() => {
if (resetting.current) {
// skip useEffect if we are in handleReset()
resetting.current = false; // change resetting to false
return;
}
if (someCondition) {
// do stuff
}
}, [values]); // you don't need resetting.current as a dependency. It's a ref, and the useEffect would be triggered by the values change
const handleReset = () => {
resetting.current = true;
setValues(getDefaultValues());
};
return ();
};