I was recently looking through the Material UI documentation for their <Stepper> component. In their implementation of the Horizontal Linear Stepper, they used the useState React Hook to set the state.
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.
Here’s what that could look like.
React Hooks Version
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;
React Class Component Version
To put this in perspective, let’s look at how this looks with a class component.
import React, { useState } 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 })
}
Resources:
How to use the increment operator in React | Stack Overflow
Stepper React component | Material-UI
    
Top comments (1)
I believe I saw that pattern on Twitter somewhere where it's used to rid of a dep in
useEffectand I couldn't find that in React documentation either.Maybe you can PR to the React documentation 😉