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

Next 13 throws when useLayoutEffect is imported, even if it's not possible for it to run #49714

Open
1 task done
RJFelix opened this issue May 12, 2023 · 4 comments
Open
1 task done

Comments

@RJFelix
Copy link

RJFelix commented May 12, 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: arm64
      Version: Darwin Kernel Version 22.3.0: Thu Jan  5 20:48:54 PST 2023; root:xnu-8792.81.2~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 16.14.0
      npm: 8.3.1
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.4.3-canary.0
      eslint-config-next: 13.4.1
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.0.3

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

App directory (appDir: true)

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/confident-meadow-tugfro

To Reproduce

Install and run the provided CodeSandbox example.

Describe the Bug

When I import a library that contains components that use useLayoutEffect as well as other non-component code in order to call a non-component function in the app/layout.tsx file, Next throws merely because useLayoutEffect was imported, even though it's not called - and not even possible to use, because the imported function is run outside a render function.

Expected Behavior

It should only throw if we try to actually call useLayoutEffect on the server. It should not throw merely because useLayoutEffect is imported somewhere in a library. (I believe this was the Next 12 behavior.)

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@RJFelix RJFelix added the bug Issue was opened via the bug report template. label May 12, 2023
@pckilgore
Copy link

Possible related to #49355

@sannajammeh
Copy link
Contributor

Related to vercel/swr#2632

@shuding
Copy link
Member

shuding commented May 19, 2023

useLayoutEffect is not available in Server Actions and currently that's a syntax error in compilation. That's because it might be used in the future because it's part of the dependencies. It will be really bad if it passes build but fails on production, e.g.:

import { useLayoutEffect } from 'react'

function Foo() {
  useLayoutEffect()
}

function Page() {
  return cond ? <Foo/> : null
}

This will error even if <Foo> isn't rendered during build, to prevent potential errors when running the app.

There're two workarounds, one is to use require('react').useLayoutEffect so the compiler won't complain about it. Or make Foo a client component where useLayoutEffect is available there.

@RJFelix
Copy link
Author

RJFelix commented May 23, 2023

If it helps, this particular case seems to be from the @xstate/react library invoking React.useSyncExternalStore via React's use-sync-external-store shim.

If the built-in useSyncExternalStore is present, then the shim is just an alias for it (src/useSyncExternalStoreShim.js). But the shim's code that uses useLayoutEffect is still there in the bundle.

Does it seem a bit unusual that a dependency using React's official shim for a method that is supported in server rendering would cause Next to throw?

@samcx samcx removed bug Issue was opened via the bug report template. area: app labels Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants