React hooks are great. Released with version 16.8 in 2019, React hooks allow React function components to use state similarly to how class components do. Despite being around a couple years, many of us are still learning them and of course part of learning a new feature is breaking things. In this article we will tackle the React Hook "useState" is called in function which is neither a React function component or a custom React hook function
error.
Fortunately this is one of those errors that provides enough information in the message itself to help get to the root of the problem. From the message, we can tell that there are two acceptable situations to use a React hook: within a React function component or within a custom React hook function. Let’s look at that first option.
The official React documentation says that a valid React function component is one that “accepts a single ‘props’ object argument with data and returns a React element.” Here are a few examples of invalid React function components that would trigger this error.
const myComponent = () => {
const [state, setState] = useState(null);
return <div>myComponent</div>;
};
Code language: JavaScript (javascript)
In the above example, everything looks good except one thing. In React, components must start with a capital letter in their definition.
class MyComponent extends React.Component {
render() {
const [state, setState] = useState(null);
return <div>My Component</div>;
}
}
Code language: JavaScript (javascript)
While you won’t get the same error, this is an example of the same component built as a class component. This would not work because you cannot use useState
in a component that is not a function component.
The other valid usage of useState
would be within a custom hook. Here’s an example of an invalid custom hook:
const customHook = () => {
const [state, setState] = useState(null);
return state;
};
Code language: JavaScript (javascript)
Similar to the above example with capitalization, this hook is invalid because it does not start with use
in its name.
As you can imagine, these three examples are all pretty easy to solve once you know they are the problem in the first place. If you intend to use useState
in a component, make sure that component starts with a capital letter and is a function component (not a class component).
const MyComponent = () => {
const [state, setState] = useState(null);
return <div>My Component</div>;
};
Code language: JavaScript (javascript)
For custom hooks, make sure your hook starts with use
in its name.
const useMyCustomHook = () => {
const [state, setState] = useState(null);
return state;
};
Code language: JavaScript (javascript)
Fortunately, React has a plugin called eslint-plugin-react-hooks for ESLint that can help point out these syntax problems before they leave you stumped. If you are using Create React App, this plugin is likely already configured behind the scenes. If not, you can install it as a dev dependency and then run ESLint on your project regularly to avoid this error altogether.
This is one of our first React articles so please feel free to leave feedback if you have it. Otherwise, check out our library of articles and we’ll see you in the next one. Thanks!