React: useCallback returns undefined when the component is rendered server-side

Created on 15 Nov 2018  ·  4Comments  ·  Source: facebook/react

Do you want to request a feature or report a bug?

Bug.

What is the current behavior?

React.useCallback returns undefined when the component is rendered server-side.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

This bug can be reproduced by creating a React component using a useCallback. Logging the return value on the server yields undefined while it properly returns the function in the browser.

You can observe this bug in this CodeSandbox: https://codesandbox.io/s/r557kww6wn The application is properly rendered to a string bug looking at the console, you will see that the return value of useCallback is undefined.

Here's the exact same application but rendered on the client: https://codesandbox.io/s/xvwv797pxz The function is properly logged to the console.

What is the expected behavior?

React.useCallback should return the memoized callback, not undefined.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

  • react: 16.7.0-alpha.2
  • react-dom: 16.7.0-alpha.2
Hooks Bug

Most helpful comment

I believe this is a bug; that code comment is wrong. My understanding is it is correct to use useCallback for render phase callbacks.

All 4 comments

This is intentional behavior.

Callbacks are not executed on server environment.

I presume that the rationale is that since callbacks are for usage with event handlers such as onClick, which aren't meaningful during SSR, React doesn't really need to keep track of them, freeing resources that would be used unnecessarily by keeping track of hooks that would never be used.

Don't worry, when rehydrating, the callbacks will be there.

But, may I ask what exactly are you trying to do?

Thanks @arianon 👌 I was following redux-react-hook's suggestion to use useCallback with their useMappedState. Conceptually, the function I am memoizing is not really a callback. I didn't pay attention to that at first because the term tends to be used in a variety of context. Also, the documentation mentions that:

useCallback(fn, inputs) is equivalent to useMemo(() => fn, inputs).

I'll open an issue on the docs repository to suggest an update 😉 Thanks again!

I believe this is a bug; that code comment is wrong. My understanding is it is correct to use useCallback for render phase callbacks.

AFAICT the only things that should not run server side are Effects and ref attribute initialization. A working useCallback is important for, for example, the render prop HOC pattern, which will still be with the ecosystem for a long time.

Was this page helpful?
0 / 5 - 0 ratings