18

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()?

2
  • i think it is ok to have multiple set state as React will wait for event handling to finish before re-rendering. stackoverflow.com/questions/33613728/… Commented Oct 17, 2018 at 4:42
  • You might want to change the title; if I'm understanding you right you're changing multiple objects in the state, but not changing the internals of any object in the state. Which is what, to me, 'nested' implies. Commented Oct 17, 2018 at 4:54

4 Answers 4

24

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)
    );
Sign up to request clarification or add additional context in comments.

1 Comment

Upvoted 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.
10

you can change multiple properties of a state like this.

this.setState({ openedCard: null, offeredChips: 0, activePlayer: nextPlayer });

Comments

1

For functional components, the basic syntax to update more than one property at once is as follows:

function handleUserData() {
  setUserData((prevUserData) => {
    return {
      ...prevUserData,
      propertyName: theValueOrVariableHere,
      otherPropertyName: theValueOrVariableHere
    }
  })
}

Comments

0

you can change multiple properties of a state like this.this.setState({value1: 0, value2: 0})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.