web-dev-qa-db-ja.com

(同時に)反応する状態の複数のプロパティを変更するにはどうすればよいですか?

私のメインの親コンポーネントにこの状態があります:

_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
        }
    ]
};  
_

これで、状態のさまざまなプロパティを変更するメソッドがいくつかあります。例えば。:

_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!");
    }

};
_

ご覧のとおり、1回のクリックイベントだけで変更されるプロパティが多数あります(このメソッドはクリックイベントにアタッチされています)。これが適切な方法なのか、またはすべてのsetState()を組み合わせる必要があるのか​​と思います。

4
catandmouse

Reactは内部でsetStateの前にバッチ処理を行うため、renderを1回だけ呼び出すため、複数のsetStatesを呼び出すことはできます。つまり、setStateの記述を間違える可能性はバッチ処理は変更を無視するか、正しくない値を設定します(たとえば、前の値に基づいて同じキーに対してsetStateを2回呼び出すことがあり、得られる結果とは異なる結果が予想される場合があります)。したがって、すべての処理後にsetStateを1回呼び出すことをお勧めします。その価値

    // 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)
    );
7
Shubham Khatri

このように状態の複数のプロパティを変更できます。

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