KINDERAS.COM

Wed May 04 2022

Fixing the React «Invalid hook call» warning for Next.js projects

When working directly with React, or in this example, with Next.js (which is build on top of React), you can be unlucky and hit the notorious «Invalid Hook Call Warning». As the React documentation explains, there can be several reasons for this warning/error. In this post I'll deal with one case where you might have multiple versions of react in a monorepo. This can also occur when working with multiple packages such as component libraries and using yarn link or npm link.

Note that this might not fix this problem in all cases, but it did the trick in my case. The case tested had one React component library and two Next projects in one monorepo (no yarn|npm) link.
Important: If you have set outputStandalone: true under the experimental flag in the next config, then this will prevent your build from running properly when in a yarn workspace!
Invalid Hook Call Warning
Invalid Hook Call Warning

This is an issue you might spend days on trying to fix, I certainly did. So, if you find your self in the situation where this error is facing you, I hope this helps.

The solution

The solution entails making some adjustments to the webpack config for the Next project. Now, this assumes that you have the following setup:

  • A react library (components so on) in a monorepo or linked to the Next app using yarn|npm link
  • A Next application which is using the library as mentioned above

What you need to do is to add the following to the next.config.js file in for the Next project.

// next.config.js
const path = require("path");

/** @type {import('next').NextConfig} */
const nextConfig = {
    // Your config here
    
    webpack: (config) => {
        // This fixes the invalid hook React error which
        // will occur when multiple versions of React is detected
        // This can happen since common project is also using Next (which is using React)
        const reactPaths = {
            react: path.join(__dirname, "node_modules/react"),
            "react-dom": path.join(__dirname, "node_modules/react-dom"),
        };
        config.resolve = {
            ...config.resolve,
            alias: {
                ...config.resolve.alias,
                ...reactPaths,
            },
        };
        return config;
    },
};

module.exports = nextConfig;

What's happening here is that we're telling Webpack to use (and only use) the version of React and react-dom found in the node_modules folder of the Next project. And critically, not use any other instance of React derived from any linked packages (such as a react library or similar).

By doing this there will only be one instance of React running in the project and you should avoid seeing the «Invalid Hook Call Warning» in the future.

Sources