mit(e) {
        e.preventDefault();
        setTimeout(() => {
          alert(`You said ${message} to ${to}`);
        }, 5000);
      }
    
      return (
        <form onSubmit={handleSubmit}>
          <label>
            To:{' '}
            <select
              value={to}
              onChange={e => setTo(e.target.value)}>
              <option value="Alice">Alice</option>
              <option value="Bob">Bob</option>
            </select>
          </label>
          <textarea
            placeholder="Message"
            value={message}
            onChange={e => setMessage(e.target.value)}
          />
          <button type="submit">Send</button>
        </form>
      );
    }
    
    

Show more

##  Ready to learn this topic?

Read **[ State as a Snapshot ](/learn/state-as-a-snapshot) ** to learn why
state appears “fixed” and unchanging inside the event handlers.

[ Read More  ](/learn/state-as-a-snapshot)

* * *

##  Queueing a series of state updates

This component is buggy: clicking “+3” increments the score only once.

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    import { useState } from 'react';
    
    export default function Counter() {
      const [score, setScore] = useState(0);
    
      function increment() {
        setScore(score + 1);
      }
    
      return (
        <>
          <button onClick={() => increment()}>+1</button>
          <button onClick={() => {
            increment();
            increment();
            increment();
          }}>+3</button>
          <h1>Score: {score}</h1>
        </>
      )
    }
    
    

Show more

[ State as a Snapshot ](/learn/state-as-a-snapshot) explains why this is
happening. Setting state requests a new re-render, but does not change it in
the already running code. So ` score ` continues to be ` 0 ` right after you
call ` setScore(score + 1) ` .

    
    
    console.log(score);  // 0  
    
    
    setScore(score + 1); // setScore(0 + 1);  
    
    
    console.log(score);  // 0  
    
    
    setScore(score + 1); // setScore(0 + 1);  
    
    
    console.log(score);  // 0  
    
    
    setScore(score + 1); // setScore(0 + 1);  
    
    
    console.log(score);  // 0

You can fix this by passing an _updater function_ when setting state. Notice
how replacing ` setScore(score + 1) ` with ` setScore(s => s + 1) ` fixes the
“+3” button. This lets you queue multiple state updates.

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    import { useState } from 'react';
    
    export default function Counter() {
      const [score, setScore] = useState(0);
    
      function increment() {
        setScore(s => s + 1);
      }
    
      return (
        <>
          <button onClick={() => increment()}>+1</button>
          <button onClick={() => {
            increment();
            increment();
            increment();
          }}>+3</button>
          <h1>Score: {score}</h1>
        </>
      )
    }
    
    

Show more

##  Ready to learn this topic?

Read **[ Queueing a Series of State Updates ](/learn/queueing-a-series-of-
state-updates) ** to learn how to queue a sequence of state updates.

[ Read More  ](/learn/queueing-a-series-of-state-updates)

* * *

##  Updating objects in state

State can hold any kind of JavaScript value, including objects. But you
shouldn’t change objects and arrays that you hold in the React state directly.
Instead, when you want to update an object and array, you need to create a new
one (or make a copy of an existing one), and then update the state to use that
copy.

Usually, you will use the ` ... ` spread syntax to copy objects and arrays
that you want to change. For example, updating a nested object could look like
this:

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sa