Answer the question
In order to leave comments, you need to log in
Why is the connection to the fresh state lost when using requestAnimationFrame?
I have already come up with a crutch on how to fix this, but I really want to gain a real understanding of why this is happening. Here is a simplified piece of code:
export default function SomeComponent() {
const [playing, setPlaying] = useState(false);
const togglePause = () => {
const newPlaying = !playing;
setPlaying(newPlaying);
if (newPlaying) {
start();
} else {
stop();
}
};
const start = () => {
log();
};
const stop = () => {
// some code
};
const log = () => {
// console.log('log(): ', playing);
if (playing) requestAnimationFrame(log);
};
return (
<div>
<div className={styles.btn}>
<AppButton onClick={togglePause}>
{ playing ? 'Stop' : 'Start' }
</AppButton>
</div>
</div>
);
}
playing
becomes false
. Unfortunately, during the recursion, the log() function for some reason stops receiving a fresh state and never knows that the variable playing
has become false
. At the same time, the value of the variable changes correctly and this can be seen both in the rendered template and in other functions. I tried moving the control function call after changing the value playing
to the hook useEffect()
:...
const togglePause = () => {
setPlaying(!playing);
};
useEffect(() => {
if (playing) {
startListening();
} else {
stopListening();
}
}, [playing])
...
log()
did not go away. As a result, I started another variable - playingRef
using useRef()
. It completely duplicated the variable playing
and changed simultaneously with it. This allowed me to log
rely on in the function playingRef
because it was always fresh, and in JSX to rely on playing
because it playingRef
did not respond to value changes. In total, it turns out that everything works, but most importantly, I did not understand why the log()
fresh state was not picked up inside the recursion.
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question