DEV Community

Stephen Charles Weiss
Stephen Charles Weiss

Posted on • Originally published at stephencharlesweiss.com on

8

Incrementing State In Functional Components

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

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (1)

Collapse
 
dance2die profile image
Sung M. Kim

setActiveStep(prevActiveStep => prevActiveStep - 1)

which wasn’t defined anywhere else.

I believe I saw that pattern on Twitter somewhere where it's used to rid of a dep in useEffect and I couldn't find that in React documentation either.

Maybe you can PR to the React documentation 😉

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay