DEV Community

Stephen Charles Weiss
Stephen Charles Weiss

Posted on • Originally published at stephencharlesweiss.com on

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

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 😉