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

Using async for a component marks with 'use client' completely hangs the app #50898

Closed
1 task done
juvaly opened this issue Jun 7, 2023 · 10 comments · Fixed by #51547
Closed
1 task done

Using async for a component marks with 'use client' completely hangs the app #50898

juvaly opened this issue Jun 7, 2023 · 10 comments · Fixed by #51547
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. locked

Comments

@juvaly
Copy link

juvaly commented Jun 7, 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: Mon Jan 30 20:39:35 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T8103
    Binaries:
      Node: 18.16.0
      npm: 9.2.0
      Yarn: 1.22.10
      pnpm: N/A
    Relevant packages:
      next: 13.4.5-canary.7
      eslint-config-next: 13.4.4
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.0.4

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

App directory (appDir: true)

Link to the code that reproduces this issue or a replay of the bug

To Reproduce

Mark any page with 'use client', and the default exported component function with async.

Describe the Bug

The page will run into and endless loop, and hang the browser

Expected Behavior

Just the same as when using 'useState' in a component fails to compile with an error requiring 'use client', this should also fail to compile with an error.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@juvaly juvaly added the bug Issue was opened via the bug report template. label Jun 7, 2023
@github-actions github-actions bot added the area: app App directory (appDir: true) label Jun 7, 2023
@marvinjude
Copy link

I'm hitting the same thing. Here's what the error looks like:

- event compiled successfully in 48 ms (317 modules)
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
- error TypeError: Cannot read properties of null (reading 'useState')
    at Page (./src/app/page.tsx:37:90)
- wait compiling /favicon.ico/route (client and server)...
- event compiled successfully in 63 ms (293 modules)

The invalid-hook-call warning may be a pointer to the main issue 🤔

@juvaly are you hitting the same error?

@welpie21
Copy link

welpie21 commented Jun 7, 2023

I have the same issue here on a windows 11 machine. My laptop is spinning hot when i do those combinations in a file. Not sure what causes it but cpu also spikes to like above 50 when i open up where the file is with an async component and "use client" on top of the file ( see screenshot )

image

note: i do not get any errors.

@fullstackwebdev
Copy link

ran into the same problem. causes an infinite loop in my browser and hangs the tab

frontend:dev: Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
frontend:dev: 1. You might have mismatching versions of React and the renderer (such as React DOM)
frontend:dev: 2. You might be breaking the Rules of Hooks
frontend:dev: 3. You might have more than one copy of React in the same app
frontend:dev: See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
frontend:dev: - error TypeError: Cannot read properties of null (reading 'useState')
frontend:dev:     at Page (./src/components/Sidebar.tsx:45:86)

```    const [showModal, setShowModal] = useState(true);



@PegeDev
Copy link

PegeDev commented Jun 11, 2023

ran into the same problem. causes an infinite loop in my browser and hangs the tab

frontend:dev: Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
frontend:dev: 1. You might have mismatching versions of React and the renderer (such as React DOM)
frontend:dev: 2. You might be breaking the Rules of Hooks
frontend:dev: 3. You might have more than one copy of React in the same app
frontend:dev: See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
frontend:dev: - error TypeError: Cannot read properties of null (reading 'useState')
frontend:dev:     at Page (./src/components/Sidebar.tsx:45:86)

```    const [showModal, setShowModal] = useState(true);

is there any solution for this problem?

@juvaly
Copy link
Author

juvaly commented Jun 11, 2023 via email

@kylehg
Copy link

kylehg commented Jun 14, 2023

Just confirming this issue here as well, though there wasn't any indication in my error logs what the problem was and I was going mad till I found this issue; I had page.tsx exporting an async component that I had switched to using 'use client' and didn't remove the async, and it would load fine, but on any change, the browser tab would get stuck on a pending request and crash, with no indication anything was wrong in the console.

Hopefully there can be a better error message!

@juvaly
Copy link
Author

juvaly commented Jun 14, 2023

If you work alone on a project then simply encountering this issue will take you a few days to figure out but you will never forget the solution for next time.

If you work with a team and want others to be able to avoid this, throw an eslint plugin into your project. To do that create a file named and put this code in it:

module.exports = {
  'no-async-when-use-client': {
    meta: {
      type: 'problem',
      docs: {
        description: 'Disallow async keyword for default exported components that use "use client"',
        category: 'Best Practices',
        recommended: true,
      },
      fixable: null,
      schema: [],
    },

    create(context) {
      return {
        ExportDefaultDeclaration(node) {
          const sourceCode = context.getSourceCode();
          const componentNode = node.declaration;

          if (
            componentNode.type === 'FunctionDeclaration' ||
            (componentNode.type === 'FunctionExpression' && componentNode.id)
          ) {
            const functionName = componentNode.id ? componentNode.id.name : '<anonymous>';

            const componentLines = sourceCode.getLines(componentNode.loc.start.line, componentNode.loc.end.line);
            const usesUseClient = hasUseClient(componentLines);
            const isAsync = componentNode.async;

            if (usesUseClient && isAsync) {
              context.report({
                node: componentNode,
                message: `Default exported component '${functionName}' should not be declared as async when component is declared 'use client'`,
              });
            }
          }
        },
      };
    }
  }
};

function hasUseClient(lines) {
  for (const line of lines) {
    const trimmedLine = line.trim();

    if (trimmedLine.includes('use client')) return true;
  }

  return false; 
}

Then run yarn add eslint-plugin-local-rules --dev and edit your eslint.json file to look like this:

{
  "extends": "next/core-web-vitals",
  "plugins": [ "eslint-plugin-local-rules" ],
  "rules": {
    "local-rules/no-async-when-use-client": "error"
  }
}

This will at least throw an error at build time.

@juvaly juvaly closed this as completed Jun 14, 2023
@juvaly juvaly reopened this Jun 14, 2023
@leandronorcio
Copy link

removing the async keyword will fix the problem for you.

On Sun, Jun 11, 2023, 1:32 PM Alfath Ra @.> wrote: ran into the same problem. causes an infinite loop in my browser and hangs the tab frontend:dev: Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: frontend:dev: 1. You might have mismatching versions of React and the renderer (such as React DOM) frontend:dev: 2. You might be breaking the Rules of Hooks frontend:dev: 3. You might have more than one copy of React in the same app frontend:dev: See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. frontend:dev: - error TypeError: Cannot read properties of null (reading 'useState') frontend:dev: at Page (./src/components/Sidebar.tsx:45:86) ``` const [showModal, setShowModal] = useState(true); is there any solution for this problem? — Reply to this email directly, view it on GitHub <#50898 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOAANACRNZFYYTDIIZE2IDXKWNCVANCNFSM6AAAAAAY5YIF44 . You are receiving this because you were mentioned.Message ID: <vercel/next .@.>

In my case it hangs because of an infinite re-rendering of the client component, there was no error in the console too. I've found out about this by adding a console.log('re-render') in my client component. Removing the async in my client fixed this issue for me.

@reinierkaper-carewell
Copy link

We can confirm this problem as well with async client components and useState

@github-actions
Copy link
Contributor

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 Jul 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. locked
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants