DEV Community

Chris Colborne
Chris Colborne

Posted on • Originally published at chriscolborne.com on

1 1

Is it ever OK to set state directly? A setState cheat sheet

One of the parts of React that trips people up is understanding state and how to update it. A lot of this confusion comes from the fact that setState is asynchronous.

As they write in the React docs:

Think of setState() as a request rather than an immediate command to update the component.

(Note: I’ll be referring to setState, but it applies equally to the useState hook which we’ll cover later)

So if I want to update immediately, I should just update the state object directly… right?

this.state.myValue = 'newValue';

NO! If you do this, you’re opting out of React’s handling, and your component won’t re-render.

The reason setState exists is to allow React to produce a more efficient and better experience for the end user. By batching the state updates, it can prevent needless re-renders and can allow React to do even more smart handling of different priority updates, aka concurrent mode.

OK, OK, I’ll use setState. But what about the weird updater function syntax? Surely I don’t need that?

Actually you do.

setState (and useState) have two forms, the updater function and the stateChange object syntax.

// Updater function
// pass a function to show what to update
this.setState(prevState => {
  return { count: prevState.count + 1 };
});

// stateChange object
// pass an object to show what to update
this.setState({ name: 'New Name' });
Enter fullscreen mode Exit fullscreen mode

Which one should I use when?

Here’s a quick rule of thumb.

If your next state depends on the current state, use the updater function. Otherwise you’re fine to pass an object in the stateChange syntax.

For example:

  • updating a count (updater function)
  • updating an object (updater function)
  • toggling a boolean (updater function)
  • setting a new string value (stateChange object)

What about hooks and useState?

All the cases above apply equally to the useState hook.

Where you would use the updater function in setState, use the updater function in your hook setter function.

See the below examples in both setState and useState hook.

So how about that cheat sheet?

Most situations can be boiled down to one of a few examples, shown below:

Updating a count

Relies on previous state, use updater function

// this.setState()
this.setState(prevState => {
  return { count: prevState.count + 1 };
});

// useState hook
const [count, setCount] = useState(0);
setCount(prevCount => prevCount + 1);
Enter fullscreen mode Exit fullscreen mode

Updating an object

Relies on previous state, use updater function

// this.setState()
this.setState(prevState => {
  return { config: { ...prevState.config, ...updatedValues } };
});

// useState hook
const [config, setConfig] = useState({});
setConfig(prevConfig => ({ ...prevConfig, ...updatedValues }));
Enter fullscreen mode Exit fullscreen mode

Toggling a boolean

Relies on previous state, use updater function

// this.setState()
this.setState(prevState => {
  return { isEnabled: !prevState.isEnabled };
});

// useState hook
const [isEnabled, setIsEnabled] = useState(true);
setIsEnabled(prevIsEnabled => !prevIsEnabled);
Enter fullscreen mode Exit fullscreen mode

Setting a new string value

Doesn’t rely on previous state, use stateChange object

// this.setState()
this.setState({ stringValue: "doesn't rely on previous state" });

// useState hook
const [stringValue, setStringValue] = useState('a default string');
setStringValue("doesn't rely on the previous state");
Enter fullscreen mode Exit fullscreen mode

To wrap up

Component state is one of the main concepts you need to understand in React. Remember these simple rules and you’ll never be confused by setState again!

  1. Never change state directly: always use setState or the useState setter function.
  2. If your next state depends on the current state, use the updater function.

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (0)

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