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.
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.
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:
useState
with setState
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)
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!