11

I'm currently creating a component library which is included in a Nextjs project via NPM link and having a hard time getting it to consistently load without errors. The latest one is

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

This is a Typescript component, but as far as I can tell, what I've done is okay but it's just not playing sport. Here's the code:

        import React, { useEffect } from "react";
        import { FlagIcon } from "react-flag-kit";

        const LanguageSwitcher = () => {
            useEffect(() => {
                alert('Yo!');
            })
            return (
                <div className="w-full justify-end">
                    <button>
                        <div className="flex items-center">
                            <FlagIcon code="GB" /> <span className="block ml-2">English</span>
                        </div>
                    </button>
                </div>
            )
        }

        export default LanguageSwitcher

This is then being imported into another component in the library and then imported into the Nextjs page. Which is where the error is showing up.

I'm not sure if it's a webpack or typescript compiling issue, tried all the different targets I can think of, tried googling all sorts of things but nothing seems relevant to my situation. It might not even be a React issue but one with Typescript and Webpack, but my exposure to those is very new.

My webpack config:

        var path = require('path');
        module.exports = {
          entry: './src/index.ts',
          devtool: "source-map",
          output: {
            path: path.resolve(__dirname, 'build'),
            filename: 'index.js',
            libraryTarget: 'commonjs2'
          },
          module: {
            rules: [
              {
                test: /\.ts(x?)$/,
                use: 'ts-loader',
                exclude: /node_modules/,
              },
              {
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader"
              }
            ]
          },
          resolve: {
            extensions: [ '.tsx', '.ts', '.js' ],
          }
        };

My tsconfig.json


    {
      "compilerOptions": {
        "outDir": "build",
        "module": "esnext",
        "target": "es6",
        "lib": ["es6", "dom", "es2016", "es2017"],
        "sourceMap": true,
        "allowJs": false,
        "jsx": "react",
        "declaration": true,
        "moduleResolution": "node",
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "suppressImplicitAnyIndexErrors": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "allowSyntheticDefaultImports": true
      },
      "include": ["src"],
      "exclude": ["node_modules", "build"]
    }

Any pointers or help would be really appreciated!

I also tried reverting everything back to vanilla JS and the problem persists, so I think it might be webpack related?

Edit

Here is my full package.json file and also what Nextjs has

{
  "name": "some/package",
  "version": "1.0.0",
  "description": "",
  "main": "build/index.js",
  "scripts": {
    "test": "jest",
    "start": "webpack --watch --mode=development",
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "16.10.2",
    "webpack": "^4.41.1"
  },
  "devDependencies": {
    // ...
    "@types/react": "^16.9.5",
    "@types/react-dom": "^16.9.1",
    "react": "16.10.2",
    "react-dom": "^16.10.2",
    "ts-loader": "^6.2.0",
    "typescript": "^3.6.4",
    "webpack-cli": "^3.3.9"
  }
}
    "react": "16.10.2",
    "react-dom": "16.10.2"
Alec Ritson
  • 392
  • 1
  • 13

2 Answers2

7

Turns out this was due to issues with the symlinked react in the component library

https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

Fixed by running the steps in the link:

npm link ../myapp/node_modules/react // Run within the component library
Alec Ritson
  • 392
  • 1
  • 13
0

Was facing the same issue. However, the component library is not owned by me, hence had to things out using this dependency resolution by 'Yarn'

This was my initial dependency tree

project
|- componentLibrary
|  |- react@16.10
|  |- react-dom@16.10
|- react@17.0.1
|- react-dom@17.0.1

added the following snippet in my package.json

"resolutions": {
  "componentLibrary/react": "17.0.1",
  "componentLibrary/react-dom": "17.0.1"
},

which resolved my dependencies to the project's react and react-dom.