Whenever I try and use a hook in my app, I get the Hooks can only be called inside the body of a function component
error. I'm using a standard webpack4/babel config, with preset-env
and preset-react
plugins. My react/react-dom versions are pinned to 16.8.4
using yarn resolutions, so there should not be a mismatch in React/dom versions.
This is on the most basic of usages:
import React, { useState } from "react";
function MyComp() {
const [hello] = useState(0);
return <div>HELLO {hello}</div>;
}
export default MyComp;
I have checked the gotchas listed https://reactjs.org/warnings/invalid-hook-call-warning.html with no luck.
Is there anything else that I need to include?
Stack Snippet version from T.J. Crowder (which works):
const { useState } = React;
function MyComp() {
const [hello] = useState(0);
return <div>HELLO {hello}</div>;
}
ReactDOM.render(
<MyComp />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
EDIT: Debugging the error reveals that
function resolveDispatcher() {
var dispatcher = ReactCurrentDispatcher.current;
!(dispatcher !== null) ? invariant(false, 'Hooks can only be called inside the body of a function component. (/* omitted url due to warning */ )') : void 0;
return dispatcher;
}
in react.development
such that dispatcher
is null. Would this still suggest that I am not using the correct version of React/DOM, even though yarn list
informs me that they're both at 16.8.4?
EDIT2: console.log
-ing a count in the parent's render function reveals
let count = 0;
class App extends Component {
render() {
count++;
console.log("counter", count++);
return (
<MyComp />
);
}
}
export default App;
Actually runs twice:
VM239 bundle.js:141088 counter 1
App.js:46 counter 1
which is very interesting - I can't explain why that would occur (my app had otherwise ran fine before I tried this experiment - but it would suggest that there could be two competing processes in conflict
The problem was with my webpack config - I was using both the HtmlWebpackPlugin whilst adding the output bundle's script tag to my index.html, as described here: All my code runs twice when compiled by Webpack
This meant that React was being included twice, causing the error. Sadly, all of my previous checks were over different versions, not 2 instances of the same version!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With