What the error? React: Hooks can only be called inside the body of a function component | Owen Conti

What the error? React: Hooks can only be called inside the body of a function component

Published on May 19, 2019 in category React.

What the error? React: Hooks can only be called inside the body of a function component

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

This is a common warning that developers run into when starting out with hooks in React. There are 3 possible reasons for this warning:

  • You may have mismatching versions of React and ReactDOM.
  • You may have more than one copy of React running in your application such that the version of React imported by ReactDOM is not that same version that you import in your application.
  • Most common: You're breaking the rules of hooks. You must only call hooks while React is rendering a function component.
  1. You cannot call hooks in class components:
class App extends React.Component {
    componentDidMount() {
        // BAD!
        const [state, setState] = React.useState(null)
    }
}
  1. You cannot call hooks inside event handlers:
function App() {
    return (
        {/* BAD! */}
        <button onClick={() => React.useState(null)}>Button you can click</button>
    );
}
  1. You cannot call hooks inside useMemo, useReducer, or useEffect:
function App() {
    React.useEffect(() => {
        // BAD!
        const [state, setState] = React.useState(null); 
    });

    return (
        <div>Custom component markup</div>
    );
}
  1. You cannot call hooks outside of React altogether:
// BAD!
const [globalState, setGlobalState] = React.useState(null); 

function App() {
    return (
        <div>Custom component markup</div>
    );
}

Instead, call hooks at the top level function of your component:

function App() {
    const [state, setState] = React.useState(null); 

    // Use the state in `useEffect`
    React.useEffect(() => {
        axios.get(`/api/${state}`);
    });

    return (
        <div>
            <button onClick={() => {
                // Use the state inside an event handler
                setState(state + 1);
            }}>Click this button</button>
        </div>
    );
}

Thanks for reading!

๐Ÿ‘‹ Hi there! I hope you enjoyed this post. If you did, follow me on Twitter, @owenconti, for updates on new posts.

If you prefer to receive updates via email, subscribe to my newsletter where I send a weekly summary of the content I've released.

Feel free to check out other posts in the React category.