xnimorz/use-debounce

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.