Invalid hook call. Hooks can only be called inside of the body of a function component
After importing a react component called Formik, I started to get the error above. The error gives me three reasons as to why it may be occuring.
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
In further combing the error, I also noticed this
react-dom.development.js:19527 The above error occurred in the component:
in Formik (created by App)
in div (created by App)
in App
that gave me the impression that the 3rd reason might be why
More than one copy of React
I looked at the package.json file for “Formik” and saw that it was bringing in a different version of react and react-dom then my project was
this is Formiks package.json file
this is mines
So I thought to myself theres gotta be a way to stop webpack from bundling up react and react-dom multiple times. Did some googling and came accross this helpful article.
https://robkendal.co.uk/blog/2019-12-22-solving-react-hooks-invalid-hook-call-warning/
Thank you to the author, Rob Kendal.
So basically I personally want to be responsible for bringing in react and react-dom. either from a separate bundle or a cdn. I picked a cdn for simplicity sake.
https://reactjs.org/docs/cdn-links.html
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
I injected the code above before I closed the </body> in my html prior to bringing in my webpack bundle
then i went over to my webpack.config.js file and set values for the externals property following the directions from the article above. “externals” are resolved first and foremost before anything else.
externals: {
'react': 'commonjs react',
'react-dom': 'commonjs react-dom',
},
re-bundled and got this error
since I’m using a cdn, I don’t need “react” to be required as if a commonjs module. If I had a separate bundle for react and react-dom then maybe. Heres my altered code
externals: {
'react': 'React',
'react-dom': 'ReactDOM',
},
‘React’ and ‘ReactDOM’ are the global variables that are exposed by the cdn files we imported. Webpack uses these values to ensure that when other modules import or require “react”, the “React” global variable is the object that is sent back. Same deal for “react-dom”.
After re-bundling, Formik seems to be working