Next.js: Invalid hook call. Hooks can only be called inside of the body of a function component.

Created on 21 Jun 2019  路  17Comments  路  Source: vercel/next.js

Bug report

Describe the bug

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://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

To Reproduce


Details
So the error points on this code

static async getInitialProps (ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage
    const {
      req: { locale, localeDataScript }
    } = ctx
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        })

      const initialProps = await Document.getInitialProps(ctx)
      return {
        ...initialProps,
        userAgent: ctx.req.headers['user-agent'],
        helmet: Helmet.renderStatic(),
        locale,
        localeDataScript,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      }
    } finally {
      sheet.seal()
    }
  }

Screenshots

Screen Shot 2019-06-21 at 12 10 08 PM

Additional context

I suspect that it treats the ctx.renderPage = () => as a react hooks.

Most helpful comment

For those who are still encountering this error after troubleshooting all the proposed fixes, double-check that you are using the correct directory casing when running your project. I continued to have problems on my PC and discovered this was the reason why.

https://stackoverflow.com/questions/58365151/hooks-error-invalid-hook-call-using-nextjs-or-reactjs-on-windows

All 17 comments

what version using styled-components? because i have same problem, but only version 5 beta broken currently

This happens to me sometimes when I update dependencies or run npm install without clearing out old node_modules or the build folder (dist).

First, make sure all dependencies are up-to-date in your package.json file, specifically react and any related react-releated dependencies like react-dom. Also, it may be that you have other dependencies that need certain versions of react. Make sure things match - usually for me, this just means the latest available version.

Then, I delete node_modudes, dist/ and package-lock.json, and re-run npm install and restart the app (which rebuilds the /dist folder. Seems to always fix it. Never comes back for me after that until the next time I edit the package.json file.

Please provide a clear and concise reproduction. I don't think this is related to Next.js based on the description provided so I'll close the issue until a full reproduction is provided. There are 2 possibilities in which this happened as described in the error message:

  • you have 2 versions of react, maybe through installing external deps
  • you are using hooks somewhere that is not in the render tree, maybe the stacktrace means you're trying to use hooks inside getInitialProps?

I'm experiencing this as well, after updating a bunch of dependencies. Difficult to pinpoint the cause. FWIW I did clear out node_modules and package-lock.json, and it did not solve the issue.

My stack trace pointed to the following line as the source of the error:

  3 | export default class DefaultDocument extends Document {
  4 |   static async getInitialProps (ctx) {
> 5 |     return await Document.getInitialProps(ctx);
  6 |   }

This seems like pretty standard boilerplate for Next, unless I'm missing something that changed in one of the recent major versions?

I'm experiencing this as well, after updating a bunch of dependencies. Difficult to pinpoint the cause. FWIW I did clear out node_modules and package-lock.json, and it did not solve the issue.

My stack trace pointed to the following line as the source of the error:

  3 | export default class DefaultDocument extends Document {
  4 |   static async getInitialProps (ctx) {
> 5 |     return await Document.getInitialProps(ctx);
  6 |   }

This seems like pretty standard boilerplate for Next, unless I'm missing something that changed in one of the recent major versions?

Yeah, i also checked if I have a 2 different react and react-dom. The result is I only have 1 which is both version 16.8.6. I'm running out of things to check.

Same here. I'm embarking on trying to put together a minimal reproduction repo.

By the way my codebase does not use any React hooks at all, so something is tricking React into thinking there's an invocation of hooks.

I'm on next 8.1.0 and React 16.8.6

Full stack trace in case it might be useful:

{ Invariant Violation: 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://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    at invariant (/home/curran/repos/vizhub/packages/ui/node_modules/react/cjs/react.development.js:88:15)
    at resolveDispatcher (/home/curran/repos/vizhub/packages/ui/node_modules/react/cjs/react.development.js:1436:28)
    at useMemo (/home/curran/repos/vizhub/packages/ui/node_modules/react/cjs/react.development.js:1491:20)
    at ConnectFunction (/home/curran/repos/vizhub/packages/ui/node_modules/react-redux/lib/components/connectAdvanced.js:131:41)
    at processChild (/home/curran/repos/vizhub/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:2888:14)
    at resolve (/home/curran/repos/vizhub/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:2812:5)
    at ReactDOMServerRenderer.render (/home/curran/repos/vizhub/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3202:22)
    at ReactDOMServerRenderer.read (/home/curran/repos/vizhub/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3161:29)
    at renderToString (/home/curran/repos/vizhub/packages/web/node_modules/react-dom/cjs/react-dom-server.node.development.js:3646:27)
    at render (/home/curran/repos/vizhub/packages/web/node_modules/next-server/dist/server/render.js:86:16)
    at renderPage (/home/curran/repos/vizhub/packages/web/node_modules/next-server/dist/server/render.js:211:20)
    at Function.value (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/_document.js:830:41)
    at _callee$ (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/_document.js:2276:77)
    at tryCatch (/home/curran/repos/vizhub/packages/web/node_modules/regenerator-runtime/runtime.js:62:40)
    at Generator.invoke [as _invoke] (/home/curran/repos/vizhub/packages/web/node_modules/regenerator-runtime/runtime.js:296:22)
    at Generator.prototype.(anonymous function) [as next] (/home/curran/repos/vizhub/packages/web/node_modules/regenerator-runtime/runtime.js:114:21)
    at asyncGeneratorStep (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/create-visualization.js:1026:24)
    at _next (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/create-visualization.js:1048:9)
    at /home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/create-visualization.js:1055:7
    at new Promise (<anonymous>)
    at new F (/home/curran/repos/vizhub/packages/web/node_modules/core-js/library/modules/_export.js:36:28)
    at Function.<anonymous> (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/create-visualization.js:1044:12)
    at Function.getInitialProps (/home/curran/repos/vizhub/packages/web/.next/server/static/development/pages/_document.js:2290:33)
    at Object.loadGetInitialProps (/home/curran/repos/vizhub/packages/web/node_modules/next-server/dist/lib/utils.js:42:35)
    at Object.renderToHTML (/home/curran/repos/vizhub/packages/web/node_modules/next-server/dist/server/render.js:218:36)
    at processTicksAndRejections (internal/process/next_tick.js:81:5) name: 'Invariant Violation', framesToPop: 1 }

I'm starting to think my case may be "might have more than one copy of React in the same app". Investigating this line of inquiry.

@curran Did you also delete the build folder? You only mention 2 of 3 that I suggested. The error message seems like a red herring each time - it seems to have more to do with miss-matched versions and out of date dependencies and builds than it does hooks.

Thanks @paintedbicycle for the tip! I tried rm .next/ -rf, and the error persists.

I'm seeing this in dev mode, so I don't believe the build folder (.next) would be related.

I have not had any luck reproducing the error in a minimal test case, which I was hoping for.

I'm using Lerna as well, which may complicate things, and may be related to this error (not sure).

I think I'm giving up on this for now (reverting to older dependency versions), but if anyone is able to reproduce with a minimal example, I think that is what's needed to take this forward.

Ah, ok I have a slightly different set up than you. I have /src/ and /dist/

I'm grappling with this one too. I don't use styled-components. I tried deleting node_modules etc. without luck. I tried adding aliases and resolves for react in my next.config.js file and package.json without luck. I'm using react 16.8.6, react-dom 16.8.6, and next 9.0.4. npm ls says there's only one of each. The app uses material-ui. I am not using any npm links.

Repository: https://github.com/dancancro/questions/tree/invalid-hook-call

Codesandbox: https://codesandbox.io/s/github/dancancro/questions/tree/invalid-hook-call/?fontsize=14

Stackoverflow: https://stackoverflow.com/questions/57647040/nextjs-invalid-hook-call-hooks-can-only-be-called-inside-of-the-body-of-a-fun

The error is here: https://gist.github.com/dancancro/2dfafb053aaaedfade406fd4f67eb68a
render -> renderToString -> ReactDOMServerRenderer.read -> ReactDOMServerRenderer.render -> Object.WithStyles [as render] ...

The offending hook is on line 17428 of this file in a withStyles function. Search for "var classes = useStyles(props)". The problem is with next-generated code. The code I wrote doesn't use withStyles or any hooks.
https://raw.githubusercontent.com/dancancro/questions/invalid-hook-call/.next/static/development/pages/index.js

UPDATE: removing this from my next.config.js solved the problem:

    webpack: config => {
        config.externals = [
            '/'
        ]
        return config
    },

I don't use next, but I do work on an SSR react app and ran into the same issue. The thing that ended up fixing it was to modify my webpack externals configuration to keep react and react-dom inside the webpack bundle.

I still have no idea why that fix worked - it makes me wonder whether there's something about the webpack runtime + nodejs requires that can result in multiple copies of a lib floating around at runtime.

For those who are still encountering this error after troubleshooting all the proposed fixes, double-check that you are using the correct directory casing when running your project. I continued to have problems on my PC and discovered this was the reason why.

https://stackoverflow.com/questions/58365151/hooks-error-invalid-hook-call-using-nextjs-or-reactjs-on-windows

I had a node_modules folder in a parent directory up the tree that was causing issues. I deleted that and it started working as expected,

@brycelund this fixed it for me, after a day of checking for duplicate reacts and ensuring my hooks were done by the book. Thanks! I can't understand why this is an issue

I don't use next, but I do work on an SSR react app and ran into the same issue. The thing that ended up fixing it was to modify my webpack externals configuration to keep react and react-dom inside the webpack bundle.

I still have no idea why that fix worked - it makes me wonder whether there's something about the webpack runtime + nodejs requires that can result in multiple copies of a lib floating around at runtime.

@tstirrat15 I am also having the same issue. Can you please share the webpack externals config which fixed the issue? Thanks a lot.

@kishankanugula I don't have access to that code anymore. It was using webpack-node-externals and adding react and react-dom to the allowList, though.

Was this page helpful?
0 / 5 - 0 ratings