Thursday, 21 March 2019

Hooks can only be called inside the body of a function component error

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



from Hooks can only be called inside the body of a function component error

No comments:

Post a Comment