Last active
February 21, 2019 18:05
-
-
Save rlogwood/b29c23bb53d49657c5f2c8c46a337432 to your computer and use it in GitHub Desktop.
Explore React setState idiom of using a function instead of an object to update state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Simple javascript to explore the React stateState function paradigm | |
node react_state_fn_upd_explore.js | |
Explore the second form of setState() that accepts a function rather than an | |
object. This is needed because React can batch state updates and | |
asynchronous state updates mean you need a function that receives its | |
current value before using values from it to set the next state | |
values. | |
Using the function form will make sure you are making your state | |
updates with the state updates that can occur in react. That function will | |
receive the previous state as the first argument, and the props at the time | |
the update is applied as the second argument | |
Keep in mind, when you call setState(), React merges the object you | |
provide into the current state. | |
see https://reactjs.org/docs/state-and-lifecycle.html | |
Correct function form, deltas to state are returned | |
this.setState((state, props) => ({ | |
counter: state.counter + props.increment | |
})); | |
*/ | |
// merge state updates with current state | |
function mergeStateChanges(curState,stateUpdates) { | |
for (key in stateUpdates) { | |
curState[key] = stateUpdates[key]; | |
} | |
} | |
// create current state | |
function createCurrentState() { | |
players = []; | |
players.push({name: "one", score : 0}); | |
players.push({name: "two", score : 0}); | |
return {title : "example", players : players}; | |
} | |
// simulate updating the players score and returning a state change | |
// function, then exercise the update and merge and show result | |
function performPlayerScoreUpdate(index, delta, getStateChangesFn) { | |
curState = createCurrentState(); | |
console.log("\n=========================="); | |
console.log(getStateChangesFn.name); | |
console.log("--------------------------"); | |
console.log("\n\tcurrent state:\n\t---------------\n",curState) | |
// call function to get state updates | |
stateUpdates = getStateChangesFn(curState) | |
console.log("\n\tstate updates:\n\t---------------\n",stateUpdates); | |
mergeStateChanges(curState,stateUpdates) | |
console.log("\n\tupdated state:\n\t---------------\n",curState); | |
} | |
// define functions for getting state updates, different versions to show the effects | |
// return the result of the score increment, this returns delta, which doesn't effect the state | |
// the players score is updated in the prevState object, which is our actual state object | |
// but the players object itself is not changed. But becasue we updated a reference to our players | |
// object in state the change to score is permanent | |
getStateChangesFn_1 = (prevState) => (prevState.players[index].score += delta); | |
// same as version 1 but add a new state item. do the score increment and then return a new state item, "team" | |
getStateChangesFn_2 = (prevState) => {prevState.players[index].score += delta; return { team: "Team React"}}; | |
// same as version 1, but explictly return a value of players in state which is assigned to the current | |
// players argument. increment the score and then update players state item with the value from previous state | |
getStateChangesFn_3 = (prevState) => {prevState.players[index].score += delta; return { players : prevState.players }}; | |
// same as version 1, but explicitly return an empty object for the state updates | |
getStateChangesFn_4 = (prevState) => {prevState.players[index].score += delta; return { }}; | |
// exercise the 4 versions of the state update function | |
performPlayerScoreUpdate(index = 1, delta = 10, getStateChangesFn_1) | |
performPlayerScoreUpdate(index = 1, delta = 20, getStateChangesFn_2) | |
performPlayerScoreUpdate(index = 1, delta = 30, getStateChangesFn_3) | |
performPlayerScoreUpdate(index = 1, delta = 40, getStateChangesFn_4) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment