Using setTimeout
didn't work for me because I needed to run a function that was closing over the props which means the out of date version of the function would run after the given timeout.
This is what I came up with instead:
const useEffectOnNextRender = (callback: React.EffectCallback) => {
const [scheduled, setScheduled] = useState(false);
useEffect(() => {
if (!scheduled) {
return;
}
setScheduled(false);
callback();
}, [scheduled]);
return () => setScheduled(true);
};
And here's the way to use this hook:
function DemoComponent() {
const [count, setCount] = useState(0);
const scheduleDisplay = useEffectOnNextRender(() => {
display();
});
const incrementAndDisplay = () => {
setCount(count + 1);
scheduleDisplay();
};
const display = () => {
console.log(count);
};
return (
<div>
<div>{count}</div>
<button onClick={incrementAndDisplay}>increment and display</button>
</div>
);
}
Notice the scheduleDisplay()
call in the incrementAndDisplay
function. If I just called display()
an out of date value of the count
variable would be logged.
Obviously this is an overly simplified example which is just meant to demonstrate the point.
Thought I would share, maybe it'll help someone in the future.
setTimeout
without specifying the delay. That's pretty much it. – Zuckerman