2019-06-04
|~2 min read
|282 words
I was recently trying to understand Material UI’s <Stepper>
component. In looking through their implementation of the Horizontal Linear Stepper, they used the useState
React Hook to set the state.1
The implementation caught my attention because of the use of a parameter, prevActiveStep
, which wasn’t defined anywhere else.
function handleBack() {
setActiveStep((prevActiveStep) => prevActiveStep - 1)
}
Digging into it, I realized that the useState
can behave very similarly to the setState
method for class components. Whereas both can set the value for a specific element in state, they can also take a function.2
Here’s what that could look like.
import React, { useState } from ‘react’;
function MyComponent() {
const [activeStep, setActiveStep] = React.useState(0);
function handleBack() {
setActiveStep(prevActiveStep => prevActiveStep - 1);
}
return (
{/*...*/}
<div>
<Button onClick={handleBack} >
Back
</Button>
</div>
{/*...*/}
}
export default MyComponent;
To put this in perspective, let’s look at how this looks with a class component.
import React from ‘react’;
class MyComponent{
constructor(props) {
super(props);
this.state = {
activeStep: 0,
}
}
function handleBack() {
this.setState( prevState => ({ activeStep: prevState.activeStep - 1});
}
return (
{/*...*/}
<div>
<Button onClick={handleBack} >
Back
</Button>
</div>
{/*...*/}
}
export default MyComponent;
I appreciate the concision of this approach, though just to be explicit, it works the same as the following by not reassigning a state variable within setState
(which React tends to complain about).
function handleBack() {
const activeStep = this.state.activeStep - 1
this.setState({ activeStep })
}
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!