node.jsreactjstypescriptnpmnpm-link

Invalid hook call on npm-link library


Issue description:

Error: 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 altered link due to stackoverflow ToS for tips about how to debug and fix this problem.

Where the issue occurs:

The issue seems to point to my library, where I have written a custom hook that uses hooks imported from React.
Here's the problematic excerpt from my code:

export const useField = <T>(
  input: T
  ...checkFunctions: Array<(...args: unknown[]) => unknown>
): [FieldType<T>, FieldHandlerFunction<T>, FieldHandlerFunction<T>] => {
  const [value, setValue] = useState(input)
  const [name, setName] = useState('')
  // Issue seems to be here ^
}

My setup was fairly normal and seems to work fine in other projects:

What I tried:

I naturally tried to fix the issue via the provided link in the error message. This appears to be an issue when linking your own library, as mentioned here

This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.

I did run the npm link ../sandbox/node_modules/react in my eformless folder, however this did not seem to help, even after closing node server the and recompiling.

Either way it seems really confusing to me, because runnign npm ls react only shows a single version of react and it should be valid, given the useState is used top-level inside a custom hook.

Reproducing the issue

Both repositories are public


Solution

    1. You might have more than one copy of React in the same app See altered link due to stackoverflow ToS for tips about how to debug and fix this problem.

    It is because you have react in your devDependencies for eformless. This causes your application to run two instances of React.

    Instead, move react to peer dependencies in eformless package.json, delete your node_modules directory and run npm install.

    By adding react to peer dependencies, you are informing your module bundler not to include react, but instead to expect that react will be made available to it by the dependent application.

    "peerDependencies": {
      "react": "^16.13.1"
    }
    

    Also, I noticed that you had checked in your node_modules directory into eformless. You should not do that. Instead, add node_modules to your .gitignore file.