Skip to content

Instantly share code, notes, and snippets.

@rlogwood
Last active February 21, 2019 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rlogwood/b29c23bb53d49657c5f2c8c46a337432 to your computer and use it in GitHub Desktop.
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
/*
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