It works in this simplified case but if their is someother higher priority update going on in the same component it will not work. The issue is that the instance of fn is always new which triggers the useEffect inside useDebouncedEffect. I think using useCallback for that would fix the issue.
functionuseDebouncedEffect(fn,deps,time){constdependencies=[...deps,fn,time];useEffect(()=>{consttimeout=setTimeout(fn,time);return()=>{clearTimeout(timeout);};},dependencies);}exportdefaultfunctionApp(){const[text,setText]=useState("");const[debounced,setDebounced]=useState("");const[count,setCount]=useState(0);constdeb=useCallback(()=>{setDebounced(text);},[text]);useDebouncedEffect(deb,[text],1000);// to mock a higher priority frequent updateuseEffect(()=>{setInterval(()=>{setCount((c)=>c+1);},500);},[]);return(<divclassName="App"><inputonChange={(e)=>{setText(e.target.value);}}value={text}/>
<p>{debounced}</p>
<p>{count}</p>
</div>
);}
Nice example. It was fun playing around with it.
It works in this simplified case but if their is someother higher priority update going on in the same component it will not work. The issue is that the instance of
fn
is always new which triggers theuseEffect
insideuseDebouncedEffect
. I think usinguseCallback
for that would fix the issue.I hadn’t thought about this! I’m going to try it out an amend the post later :). Thank you!
Not sure in every case people gonna run into this but their is a chance.