question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React Adaptive Hooks will cause attribute mismatch during server side rendering

See original GitHub issue

Hi. I saw a recent issue #2 regarding server side rendering. However, this behaviour simply hides the attribute mismatch that can happen due to the SSR phase and the client phase rendering differently.

I have built an example repo that showcases this mismatch. https://github.com/gja/react-adaptive-hooks-ssr

Apologies for just copying the relevant file (react-adaptive-hooks/network), but I didn’t have time to configure babel and whatnot for server side rendering.

Usage to start repo:

npm install
# npx webpack (if you want to recompile main.js, though it's checked in)
node .

As you can see from https://github.com/gja/react-adaptive-hooks-ssr/blob/master/src/ReactAdaptiveHooksExample.js, it should render a paragraph whose text and class are matching (ie: <p class="4g">Your Network Status Is 4g</p>). However, the ssr hydration will not resolve the classname (ie: <p class="unsupported">Your Network Status Is 4g</p>).

However, react hydrate does not go through element attributes to look for mismatches, hence these attributes will never be caught. (worse, react believes that the classname is set to 4g, while the dom has a different value, so this will not be rectified in future renders as well).

I’m not sure what the supported model is here. In the old class world, i’d have only called out to the new functions during componentDidMount, and change the behaviour that way. I’m not sure what the equivalent is in the react hooks world.

Maybe return undefined when loading, then useEffect to set loading to false, and return the correct value on the next render.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
developitcommented, Nov 15, 2019

Another option here would be to export a context provider from the module that enables/disables a “hydration mode”. It could switch hooks to provide initial unknown values, then use useEffect or a setState callback to determine when hydration has completed and re-run any hooks that need client-side-specific output.

import { AdaptiveProvider } from 'react-adaptive-hooks';

hydrate(
  <AdaptiveProvider hydrate={true}>
    <App />
  </AdaptiveProvider>
);

My guess is that emulating the server’s “unknown” state would be relatively straightforward since that codepath already exists for SSR.

h/t @devknoll for the context suggestion, which is much better than my initial idea of a singleton module with a global isHydrating flag.

1reaction
mlampedxcommented, Nov 21, 2019

@gja

It does not fix the mismatch issue, which is due to API asymmetry between the client and server, automatically. However, by using client hints to derive a reliable initial value to populate the hooks with on the server, the developer can ensure a consistent hook state and avoid this mismatch.

In cases where this option is unavailable to the developer, I think that we should either:

useEffect to calculate whether the prerequisite APIs are available now that the components are rendering on the client. This should avoid triggering a re-render in the event that the relevant APIs are unsupported in the user’s browser. If the APIs are available, then I agree with you that a re-render is necessary.

E.g.

const [unsupported, setUnsupported] = useState(true);
useEffect(() => {
  const supported = 'connection' in navigator && 'effectiveType' in navigator.connection;
  setUnsupported(!supported);
});

or

Use the AdaptiveProvider with a hydrate flag – a pattern that I have seen work well for SSR before. The provider’s context could signal to the hooks when it is appropriate for them to re-run during the hydration phase.

Read more comments on GitHub >

github_iconTop Results From Across the Web

React Adaptive Hooks will cause attribute mismatch during server ...
Hi. I saw a recent issue #2 regarding server side rendering. However, this behaviour simply hides the attribute mismatch that can happen due...
Read more >
Combining Server-Side Rendering and Responsive Design
Let's explain the challenge that comes up when mixing SSR and responsive design, and introduce a couple of possible strategies to approach ...
Read more >
Avoiding hydration mismatch when using React hooks
We follow the general rule that applies to all React hooks and components: A React hook or component MUST NOT return or render...
Read more >
Handling the React server hydration mismatch error
How to resolve the server mismatch error when hydrating a shared React component that can be used in client-side only or server-side rendered...
Read more >
Server-Side Rendering: Adaptive React Components
But with SSR, the server is not always aware of the window size. The React Hooks rely on a window resize event being...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found