Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydration errors #45246

Closed
1 task done
iscekic opened this issue Jan 25, 2023 · 2 comments · Fixed by #45565
Closed
1 task done

Hydration errors #45246

iscekic opened this issue Jan 25, 2023 · 2 comments · Fixed by #45565
Labels
bug Issue was opened via the bug report template. Lazy Loading Related to Next.js Lazy Loading (e.g., `next/dynamic` or `React.lazy`).

Comments

@iscekic
Copy link
Contributor

iscekic commented Jan 25, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 22.2.0: Fri Nov 11 02:08:47 PST 2022; root:xnu-8792.61.2~4/RELEASE_X86_64
Binaries:
  Node: 16.17.1
  npm: 8.15.0
  Yarn: 1.22.19
  pnpm: N/A
Relevant packages:
  next: 13.1.5
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Data fetching (gS(S)P, getInitialProps), Dynamic imports (next/dynamic)

Link to the code that reproduces this issue

N/A

To Reproduce

I have a couple of components which need to render client-only, eg. components with different layout based on screen width, components displaying stuff like "x seconds ago". For these, I use a helper component rendered at the root:

import { atom, useSetAtom } from "jotai";
import { useEffect } from "react";

// react hydration expects same DOM structure for SSR and initial CSR.
// as we cannot guarantee this for certain data (eg. date/time), we only render that data client-side.
export const clientMountedAtom = atom(false);

export const ClientMountedObserver = () => {
  const setClientMounted = useSetAtom(clientMountedAtom);

  useEffect(() => {
    setClientMounted(true);
  }, [setClientMounted]);

  return null;
};

The clientMountedAtom is then used by these components like this:

export const ClientOnly = () => {
  const clientMounted = useAtomValue(clientMountedAtom);

  // ... logic

  if (!clientMounted) {
    return null;
  }

  return ...;
};

Since updating to the latest version, these components have been causing hydration errors such as:

This suspense boundary received an update before it finished hydrating...

These components are often used in combination with dynamic, so that might also have an influence somehow.

Describe the Bug

See above.

Expected Behavior

No hydration errors (as in previous versions).

Which browser are you using? (if relevant)

N/A

How are you deploying your application? (if relevant)

next start

@iscekic iscekic added the bug Issue was opened via the bug report template. label Jan 25, 2023
@staaky
Copy link

staaky commented Jan 30, 2023

Might be related to #44083

In my case React 18.3 fixes these hydration errors:

"next": "^13.1.6",
"react": "18.3.0-next-ee8509801-20230117",
"react-dom": "18.3.0-next-ee8509801-20230117",

I'm probably switching back to Next 12 with React 17 though, not going to use react@next in production.

React 18.3 isn't actually fixing the problem, it just supresses the error. The error usually means suboptimal code that has to be wrapped with startTransition. I was able to optimize using the error but still had some edge cases that triggered it. Here's more details on it: facebook/react#24959 (comment)

@huozhi huozhi added the Lazy Loading Related to Next.js Lazy Loading (e.g., `next/dynamic` or `React.lazy`). label Feb 3, 2023
@kodiakhq kodiakhq bot closed this as completed in #45565 Feb 4, 2023
kodiakhq bot pushed a commit that referenced this issue Feb 4, 2023
## Issue

To address the problem that we introduced in 13.0.7 (#42589) where we thought we could use same implementation `next/dynamic` for both `pages/` and `app/` directory. But it turns out it leads to many problems, such as:

* SSR preloading could miss the content, especially with nested dynamic calls
  * Closes #45213
* Introducing suspense boundary into `next/dynamic` with extra wrapped `<Suspense>` outside will lead to content is not resolevd during SSR
  * Related #45151
  * Closes #45099
* Unexpected hydration errors for suspense boundaries. Though react removed this error but the 18.3 is not out yet.
  * Closes #44083
  * Closes #45246
 
## Solution

Separate the dynamic implementation for `app/` dir and `pages/`. 

For `app/` dir we can encourage users to: 
  * Directly use `React.lazy` + `Suspense` for SSR'd content, and `next/dynamic` 
  * For non SSR components since it requires some internal integeration with next.js.

For `pages/` dir we still keep the original implementation

If you want to use `<Suspense>` with dynamic `fallback` value, use `React.lazy` + `Suspense` directly instead of picking up `next/dynamic` 
  * Closes #45116

This will solve various issue before react 18.3 is out and let users still progressively upgrade to new versions of next.js.

## Bug Fix

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
@github-actions
Copy link
Contributor

github-actions bot commented Mar 6, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. Lazy Loading Related to Next.js Lazy Loading (e.g., `next/dynamic` or `React.lazy`).
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants