Whenever I try and use a hook in my app, I get the Hooks can only be called inside the body of a function ponent
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 .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=".8.4/umd/react.production.min.js"></script>
<script src=".8.4/umd/react-dom.production.min.js"></script>
Whenever I try and use a hook in my app, I get the Hooks can only be called inside the body of a function ponent
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/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./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./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 ponent. (/* 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 peting processes in conflict
Share edited Mar 18, 2019 at 21:21 bak202 asked Mar 18, 2019 at 17:48 bak202bak202 2773 silver badges14 bronze badges 6-
1
Please show how you use
MyComp
. If you callMyComp()
directly as a function react will plain. – UjinT34 Commented Mar 18, 2019 at 17:55 - 1 I dropped your code into a Stack Snippet (making the very minor changes required to do that) and it works just fine. Please update the snippet I've added for you to show what you're really doing so we can help you understand why it wasn't working. – T.J. Crowder Commented Mar 18, 2019 at 17:56
- Double check that you have the correct versions of react and react-dom installed. – Felix Kling Commented Mar 18, 2019 at 17:59
- I am indeed calling the ponent using standard JSX syntax, <MyComp />. Indeed, the code snippet you have kindly creates works for me as well. I have updated my question with some more information about my findings. – bak202 Commented Mar 18, 2019 at 20:59
-
Does
yarn list
list what's written in thepackage.json
or does it look at what's actually installed on your system? Directly look atnode_modules/react/package.json
andnode_modules/react-dom/package.json
. – Felix Kling Commented Mar 18, 2019 at 21:06
1 Answer
Reset to default 8The 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 piled 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!