Updating and merging state object using React useState() hook

If anyone is searching for useState() hooks update for object

  • Through Input

    const [state, setState] = useState({ fName: "", lName: "" });
    const handleChange = e => {
        const { name, value } = e.target;
        setState(prevState => ({
            ...prevState,
            [name]: value
        }));
    };
    
    <input
        value={state.fName}
        type="text"
        onChange={handleChange}
        name="fName"
    />
    <input
        value={state.lName}
        type="text"
        onChange={handleChange}
        name="lName"
    />
    
  • Through onSubmit or button click

        setState(prevState => ({
           ...prevState,
           fName: 'your updated value here'
        }));
    

Both options are valid, but just as with setState in a class component you need to be careful when updating state derived from something that already is in state.

If you e.g. update a count twice in a row, it will not work as expected if you don't use the function version of updating the state.

const { useState } = React;

function App() {
  const [count, setCount] = useState(0);

  function brokenIncrement() {
    setCount(count + 1);
    setCount(count + 1);
  }

  function increment() {
    setCount(count => count + 1);
    setCount(count => count + 1);
  }

  return (
    <div>
      <div>{count}</div>
      <button onClick={brokenIncrement}>Broken increment</button>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>