Invalid Hook Call on npm-link Library
If you’ve encountered an “Invalid hook call” error when using a linked package in your React application, you’re not alone. This issue often arises when you have multiple instances of React in your project, causing conflicts with the React hooks system. In this blog post, we’ll explore the possible causes of this error and provide solutions to help you resolve it.
The Problem: Multiple React Instances
One common reason for the “Invalid hook call” error is having multiple instances of the React library in your project. This scenario often occurs when linking your own library using npm link or a similar method.
When you run the command npm link ../sandbox/node_modules/react
in your library folder, it’s supposed to use the React copy from the application. However, in some cases, this link is not established correctly, and your bundler might “see” two different React instances – one from the application folder and one from the library folder.
Solution 1: Move React to Peer Dependencies
A common solution to this problem is to move React from dependencies
to peerDependencies
in your library’s package.json
file. By doing this, you inform your module bundler not to include React but instead expect it to be provided by the dependent application.
To move React to peer dependencies, make the following changes in your package.json
:
"peerDependencies": {
"react": "^16.13.1"
}
After making this change, delete the node_modules
directory and run npm install
. This will ensure that React is not duplicated in your dependencies and is correctly shared with the dependent application.
Solution 2: Using Webpack Alias
If moving React to peer dependencies doesn’t resolve the issue, you can try using a Webpack alias to deduplicate React dependencies in the dependent application’s build. This approach can help ensure only one version of React is being used throughout your project.
Inside the webpack.config.js
file of the application consuming the linked dependency, add the following alias:
resolve: {
alias: {
react: path.resolve(__dirname, '<app_path>/node_modules/react'),
'react-dom': path.resolve(__dirname, '<app_path>/node_modules/react-dom')
}
}
Replace <app_path>
with the actual path to your application.
Solution 3: Cleaning Up and Mapping Modules
If the previous solutions didn’t work for you, here’s an alternative approach to try:
- Delete the
node_modules
directory and runnpm install --legacy-peer-deps
. This will prevent inclusion of React and other packages in yourpeerDependencies
. - To enable running tests, map the “React imports” in your library to the React installed in your main app by adding the following configuration to your library’s
package.json
: - If you have previously linked your library’s React using
npm link
, make sure to undo it by runningnpm rm --global react
. Then, reinstall the packages in your main app usingnpm link
.
"moduleNameMapper": {
"^react$": "<rootDir>/node_modules/react",
"^react-dom$": "<rootDir>/node_modules/react-dom",
...other packages you have in your peerDependencies
}
Conclusion
The “Invalid hook call” error can be frustrating, but it can be resolved by addressing the issue of multiple React instances in your project. By following the solutions provided in this blog post and ensuring a single shared React instance, your linked package should work flawlessly within your React application.
Remember to move React to peer dependencies, set up Webpack aliases if needed, or properly clean up and map modules for correct dependency resolution.
By implementing these solutions, you can enjoy smooth development and testing experiences while leveraging your custom eformless library in your React projects.