How to change multiple properties of a state in react (at the same time)?
Solution 1
Its okay to call multiple setStates since React internally does batching before setState and hence will only call render
once. That said, the chances of you making a mistake in writing setState such that batching ignores a change or sets incorrect value are high(for instance you may call setState twice for the same key based on the previous value and might expect a result different from what you get). Hence its recommended that you call setState once after processing all the values
// Add card to active player
let playersClone = [...players];
playersClone[activePlayer].cards = [
...playersClone[activePlayer].cards,
openedCard
];
// Add any offered chips to active player
playersClone[activePlayer].remainingChips += offeredChips;
const playableCards = playableCards.filter(function(card) {
return card !== openedCard;
})
// Change active player
const nextPlayer = activePlayer === 0 ? 1 : 0;
// Reset offered chips to 0
// Reset opened card
// Remove card from deck
this.setState({
openedCard: null,
offeredChips: 0,
playableCards,
players: playersClone
}, () =>
this.calculateScore(activePlayer)
);
Solution 2
you can change multiple properties of a state like this.
this.setState({ openedCard: null, offeredChips: 0, activePlayer: nextPlayer });
Comments
-
catandmouse over 3 years
I have this state in my main parent component:
this.state = { playableCards: [], openedCard: null, offeredChips: 0, activePlayer: 0, // first player is 0, second player is 1 players: [ { name: "player1", remainingChips: 11, cards: [], score: null }, { name: "player2", remainingChips: 11, cards: [], score: null } ] };
Now, I have some methods that change different properties of the state. E.g.:
takeCard = () => { const { activePlayer, players, playableCards, offeredChips, openedCard } = this.state; if(openedCard) { // Add card to active player let playersClone = [...players]; playersClone[activePlayer].cards = [ ...playersClone[activePlayer].cards, openedCard ]; // Add any offered chips to active player playersClone[activePlayer].remainingChips += offeredChips; this.setState({ players: playersClone }, () => this.calculateScore(activePlayer) ); // Remove card from deck this.setState({ playableCards: playableCards.filter(function(card) { return card !== openedCard; }) }); // Change active player const nextPlayer = activePlayer === 0 ? 1 : 0; this.setState({ activePlayer: nextPlayer }); // Reset offered chips to 0 this.setState({ offeredChips: 0 }); // Reset opened card this.setState({ openedCard: null }); } else { console.log("Open a card first!"); } };
As you can see, there are many properties that are being changed just by a single click event (this method is attached to a click event). I am wondering whether is this the proper way of doing it or should I combine all the
setState()
? -
GD- Ganesh Deshmukh about 4 yearsUpvoted for very helpful information as:
Its okay to call multiple setStates since React internally does batching before setState and hence will only call render once.