isotropic-2022
Share
Blog
Search
Menu

How To Fix The React Hook 'useState' cannot be called in class component Error

By James LePage
|
Last updated on September 28th, 2022
|

As we continue our coverage of React content, let’s move forward by taking a step back and learning about the traditional way of creating components in React. Up until version 16.8 of React, if you wanted to maintain state in a component, you had to use a class component. That update added hooks which allowed the use of state in function components through the use of the useState function.

💡 React function components are just functions that return a React element. Class components are special ES6 classes but both are acceptable and equivalent.

Something that you may run into in your code is a mix of class and function components rather than simply choosing one or the other. If that is the case, it is important to know the difference in how you hook into state with each approach. You may run into the React hook 'useState' cannot be called in class component error if you mix up your state declarations.

The Problem

You’ve set up your class component and you’ve added state to it. Let’s say you have a component that is defined like this:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    const [count, setCount] = React.useState(0);
  }

  handleCountChange() {
    setCount(count + 1);
  }

  render() {
    return (
      <div>
        Current count: {count}
        <br />
        <button onClick={handleCountChange}>Increment</button>
      </div>
    );
  }
}Code language: JavaScript (javascript)

If you try to run this code you will run into the aforementioned error. The reason for this is you can only use useState if the component is a function component. In this case, we are working with a class component so setState must be used instead.

The Solution

As mentioned, you will need to refactor your code to use the proper state accessor depending on what type of component you are using. This leaves you with two options:

  1. Simply swap out useState with setState
  2. Refactor your component into a function component if you specifically want to use useState

Both options are viable depending on your use case so we will look at each based on the example above.

// replacing useState in a class component
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
    this.handleCountChange = this.handleCountChange.bind(this);
  }

  handleCountChange() {
    this.setState({
      ...this.state,
      count: this.state.count + 1,
    });
  }

  render() {
    return (
      <div>
        Current count: {this.state.count}
        <br />
        <button onClick={this.handleCountChange}>Increment</button>
      </div>
    );
  }
}Code language: JavaScript (javascript)

Here is the same component using function component syntax:

// refactoring into function component
function MyComponent() {
  const [count, setCount] = React.useState(0);

  const handleCountChange = () => {
    setCount((prev) => prev + 1);
  };

  return (
    <div>
      Current count: {count}
      <br />
      <button onClick={handleCountChange}>Increment</button>
    </div>
  );
}Code language: JavaScript (javascript)

Conclusion

I personally prefer the function component with state syntax because it often feels less verbose but, as mentioned before, both class and function components are valid in React despite state in function components being newer. Let us know which approach you prefer in the comments below. Thanks for reading!

The Isotropic Codex is a collection of code snippets and education for WordPress, web and WooCommerce developers.
References
Subscribe & Share
If you liked this content, subscribe for our monthly roundup of WordPress news, website inspiration, exclusive deals and interesting articles.
Unsubscribe at any time. We do not spam and will never sell or share your email.
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Article By
James LePage
Contributors/Editors
notloggedin
James LePage is the founder of Isotropic, a WordPress education company and digital agency. He is also the founder of CodeWP.ai, a venture backed startup bringing AI to WordPress creators.
We're looking for new authors. Explore Isotropic Jobs.
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram