I'm finding these two pieces of the React Hooks docs a little confusing. Which one is the best practice for updating a state object using the state hook?
Imagine a want to make the following state update:
INITIAL_STATE = { propA: true, propB: true } stateAfter = { propA: true, propB: false // Changing this property }
OPTION 1
From the Using the React Hook article, we get that this is possible:
const [count, setCount] = useState(0); setCount(count + 1);
So I could do:
const [myState, setMyState] = useState(INITIAL_STATE);
And then:
setMyState({ ...myState, propB: false });
OPTION 2
And from the Hooks Reference we get that:
Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
As far as I know, both works. So, what is the difference? Which one is the best practice? Should I use pass the function (OPTION 2) to access the previous state, or should I simply access the current state with spread syntax (OPTION 1)?
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With