# Functional setState is the future of React


By [chak-loveguir.eth](https://paragraph.com/@chak-loveguir) · 2022-06-16

---

Update: I gave a follow up talk on this topic at React Rally. While this post is more about the “functional setState” pattern, the talk is more about understanding setState **deeply**

React has popularized functional programming in JavaScript. This has led to giant frameworks adopting the Component-based UI pattern that React uses. And now functional fever is spilling over into the web development ecosystem at large.

But the React team is far from relenting. They continue to dig deeper, discovering even more functional gems hidden in the legendary library.

So today I reveal to you a new functional gold buried in React, best kept React secret — **Functional setState!**

Okay, I just made up that name… and it’s not _entirely_ new or a secret. No, not exactly. See, it’s a pattern built into React, that’s only known by few developers who’ve really dug in deep. And it never had a name. But now it does — **Functional setState!**

Going by

[Dan Abramov](https://medium.com/u/a3a8af6addc1?source=post_page-----374f30401b6b--------------------------------)

’s words in describing this pattern,**Functional setState**is a pattern where you

> _“Declare state changes separately from the component classes.”_

Huh?

Okay… what you already know
===========================

React is a component based UI library. A component is basically a function that accept some properties and return a UI element.

    function User(props) {
      return (
        <div>A pretty user</div>
      );
    }
    

A component might need to have and manage its state. In that case, you usually write the component as a class. Then you have its state live in the class `constructor` function:

    class User {
      constructor () {
        this.state = {
          score : 0
        };
      }  render () {
        return (
          <div>This user scored {this.state.score}</div>
        );
      }
    }
    

To manage the state, React provides a special method called `setState()`. You use it like this:

    class User {
      ...   increaseScore () {
        this.setState({score : this.state.score + 1});
      }  ...
    }
    

Note how `setState()` works. You pass it **_an object_** containing part(s) of the state you want to update. In other words, the object you pass would have keys corresponding to the keys in the component state, then `setState()` updates or _sets_ the state by merging the object to the state. Thus, “set-State”.

What you probably didn’t know
=============================

Remember how we said `setState()` works? Well, what if I told you that instead of passing an object, you could pass **_a function_**?

Yes. `setState()` also accepts a function. The function accepts the _previous_ state and _current_ props of the component which it uses to calculate and return the next state. See it below:

    this.setState(function (state, props) {
     return {
      score: state.score - 1
     }
    });
    

Note that `setState()` is a function, and we are passing another function to it(functional programming… **functional setState**) . At first glance, this might seem ugly, too many steps just to set-state. Why will you ever want to do this?

Why pass a function to setState?
================================

The thing is, [state updates may be asynchronous](https://facebook.github.io/react/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous).

Think about [what happens when](https://facebook.github.io/react/docs/reconciliation.html) `setState()` [is called](https://facebook.github.io/react/docs/reconciliation.html). React will first merge the object you passed to `setState()` into the current state. Then it will start that _reconciliation_ thing. It will create a new React Element tree (an object representation of your UI), diff the new tree against the old tree, figure out what has changed based on the object you passed to `setState()` , then finally update the DOM.

Whew! So much work! In fact, this is even an overly simplified summary. But trust in React!

> React does not simply “set-state”.

Because of the amount of work involved, calling `setState()` might not _immediately_ update your state.

> _React may batch multiple_ `setState()` calls into a single update for performance.

What does React mean by this?

First, “_multiple_ `setState()` _calls”_ could mean calling `setState()` inside a single function more than once, like this:

    ...state = {score : 0};// multiple setState() calls
    increaseScoreBy3 () {
     this.setState({score : this.state.score + 1});
     this.setState({score : this.state.score + 1});
     this.setState({score : this.state.score + 1});
    }...
    

Now when React, encounters “_multiple_ `setState()` _calls”,_ instead of doing that “set-state” **three whole times**, React will avoid that huge amount of work I described above and smartly say to itself: “No! I’m not going to climb this mountain three times, carrying and updating some slice of state on every single trip. No, I’d rather get a container, pack all these slices together, and do this update just once.” And that, my friends, is **batching**!

Remember that what you pass to `setState()` is a plain object. Now, assume anytime React encounters “_multiple_ `setState()` _calls”,_ it does the batching thing by extracting all the objects passed to each `setState()` call, merges them together to form a single object, then uses that single object to do `setState()` .

In JavaScript merging objects might look something like this:

    const singleObject = Object.assign(
      {}, 
      objectFromSetState1, 
      objectFromSetState2, 
      objectFromSetState3
    );
    

This pattern is known as **object composition.**

In JavaScript, the way “merging” or **composing** objects works is: if the three objects have the same keys, the value of the key of the _last object_ passed to `Object.assign()` wins. For example:

    const me  = {name : "Justice"}, 
          you = {name : "Your name"},
          we  = Object.assign({}, me, you);we.name === "Your name"; //trueconsole.log(we); // {name : "Your name"}
    

Because `you` are the last object merged into `we`, the value of `name` in the `you` object — “Your name” — overrides the value of `name` in the `me` object. So “Your name” makes it into the `we` object… `you` win! :)

Thus, if you call `setState()` with an object multiple times — passing an object each time — React will **merge**. Or in other words, it will **compose** a new object out of the multiple objects we passed it. And if any of the objects contains the same key, the value of the key of the _last_ object with same key is stored. Right?

That means that, given our `increaseScoreBy3` function above, the final result of the function will just be 1 instead of 3, because React did not _immediately_ update the state in the order we called `setState()` . But first, React composed all the objects together, which results to this: `{score : this.state.score + 1}` , then only did “set-state” once — with the newly composed object. Something like this: `User.setState({score : this.state.score + 1}`.

To be super clear, passing object to `setState()` is not the problem here. The real problem is passing object to `setState()` when you want to calculate the next state from the previous state. So stop doing this. It’s not safe!

> _Because_ `this.props` and `this.state` may be updated asynchronously, you should not rely on their values for calculating the next state.

---

*Originally published on [chak-loveguir.eth](https://paragraph.com/@chak-loveguir/functional-setstate-is-the-future-of-react)*
