Seems like useDebouncedCallback is executing async functions in render scope
Closed this issue · 2 comments
Describe the bug
I'm looking through the source here, and noticed something you may want to consider.
When you call useDebouncedCallback
in a server environment using ReactDOM.renderToString
, no async calls to requestAnimationFrame
or setTimeout
should occur. React will avoid calling useEffect
mounting code to enable this case.
Unforunately, this hook is calling setTimeout in render scope. This should be refactored to only perform side effects like enquing async callbacks in useEffect
, where you can avoid them in server scenarios and safely cancel them in client scenarios.
To Reproduce
const Component = () => {
const cb = useDebouncedCallback(() => console.log('nooo'), 1000);
cb();
return </>;
});
render this to a string in a browser using React.renderToString
, and see the message in the console 1 second later.
https://codesandbox.io/s/proud-lake-vjwqh5?file=/src/index.tsx
Expected behavior
No message in the console
use-debounce version:
reading the github code, but also 8.0.3 in the sandbox.
Hey @dzearing
Thank you for the report!
I'm curious, what is the case to call the callback in the render scope?
As it's an uncommon case.
Done with v10 release: https://github.com/xnimorz/use-debounce/releases/tag/10.0.0