Update State Based on Previous State3:30 with Guil Hernandez
Whenever you need to update state based on previous state, you shouldn't rely on
this.state to calculate the next state. State updates may be asynchronous, so it may not always lead to the component re-rendering with new data, and could cause state inconsistency.
setState() accepts a callback function that produces state based on the previous state in a more reliable way.
Our counter score is updating correctly. 0:00 However, we're still mutating or altering state directly. 0:03 Notice how we're updating the component score state by directly accessing 0:07 this.state.score. 0:11 The way setState works is it takes the object past to it with the updated 0:13 state and eventually merges it into the component's current state. 0:18 According to the React docs, a state update may be asynchronous. 0:23 In other words, 0:26 sometimes updates to the DOM don't happen immediately when you call this.setState. 0:27 If you have multiple setState calls inside of an event handler, 0:33 React will often batch, or bundle the updates together into a single update. 0:36 This is done for 0:40 performance reasons, so that your UI is rerendered more efficiently. 0:41 So because state maybe updated asynchronously, whenever you need to 0:45 update state based on previous state, like update a score based on the previous 0:50 score, you shouldn't rely on this .state to calculate the next state. 0:55 While it's technically possible to change state this way, 1:00 as you can see our counter is working just fine. 1:04 It may not always lead to the component rerendering with the new data and 1:07 could cause state inconsistency. 1:11 So instead of an object, setState also accepts a call back function 1:13 that produces state based on the previous state in a more reliable way. 1:18 So let's first modify the setState method in increment score 1:22 to take a call back function. 1:26 The call back function receives the previous state as its first argument and 1:27 the props at the time the update is applied as an optional second argument. 1:32 We are only going to check the previous value of state before setting a new value, 1:36 so let's pass the call back or 1:41 reference to the previous state with the parameter prevState. 1:43 We will add the arrow then wrap the score property in a return 1:48 statement with curly braces. 1:52 Now we'll replace this.state.score with prevState.score. 2:01 And we'll do the same with the decrement function. 2:10 Our counter still functions the same way, but 2:33 now we have a more reliable way to set state based on previous state. 2:36 Because the callback function is guaranteed to fire after the update is 2:40 applied and rendered out to the DOM. 2:45 And to make the callback more concise, you could omit the return keyword and 2:49 curly braces, by wrapping the body of the function in parentheses. 2:53 So whenever you're updating to a new state based on a previous state, 3:15 it's actively recommended that you use this approach. 3:20 That way, you can be sure that state did indeed update correctly. 3:24
You need to sign up for Treehouse in order to download course files.Sign up