ONLY call hooks inside a functional component

Have you come across this error message when trying to use a React hook?


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

Here are a few easy troubleshooting strategies you can take to solve this error.

Troubleshoot option #1: Mismatching version of React and React DOM

Make sure that you have the latest react and react-dom libraries up to date. The easiest way to make sure, is to just re-install the libraries to make sure your package.json and package-lock.json file are updated.

Run this command, within the root of your project.


npm i -S react react-dom

The -S argument will tell NPM to update your package.json file and ensure you always download the module version you just installed.

Troubleshoot option #2: Call hooks ONLY at top level

One of the rules of hooks is to always call hooks at the top level of your React function component.

This rule allows your to preserve the order of which our hooks are called each time a component renders.

Let’s look at some bad examples and a good example:

Don’t: Hooks called inside loops


const App = () => {

  for (let index = 0; index < 10; index++) {
    let [count, setCount] = React.useState(0);
    
  }

  return <h1>Do not call React hooks inside loops</h1>;
};

Don’t: Hooks called inside conditions


const App = () => {

  if (true){
    let [count, setCount] = React.useState(0);
  }

  return <h1>Do not call React hooks inside conditions</h1>;
};

Don’t: Hooks called inside nested functions


const App = () => {

  // Nested functions
  const handler = () => () => {
    const [count, setCount] = React.useState(0);
  }

  return <h1>Do not call React hooks inside nested functions</h1>;
};

Do: Call hooks at the top level


const App = () => {
  const [count, setCount] = React.useState(0);
  React.useEffect(sideEffectCallback);
  const [person, setPerson] = React.useState({});

  // Loops, conditions, nested functions, etc...

  return <h1>Good example</h1>;
};

Troubleshoot option #3: Only call hooks inside React functions

Do not call React hooks inside other regular JavaScript functions.

Let’s look at a bad example:


function useCustomHook() {
  return [count, setCount] = React.useState(0);
}

function regularFunc() {
  const [count] = useCustomHook();
}

Instead do this:


function useCustomHook() {
  const [count, setCount] = React.useState(0);

  // on mount hook
  React.useEffect(() => {
    setInterval(() => {
      setCount(state => state + 1);
    }, 1000);
  }, []);

  return count;
}

const App = () => {
  const count = useCustomHook();

  // Loops, conditions, nested functions, etc...

  return <h1>Good example: {count}</h1>;
};

Happy coding!

I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!