【问题标题】:How to change multiple properties of a state in react (at the same time)?如何在反应中(同时)更改状态的多个属性?
【发布时间】:2019-03-21 16:22:37
【问题描述】:

我的主要父组件中有这个状态:

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

};

如您所见,许多属性仅通过单击事件(此方法附加到单击事件)即可更改。我想知道这是否是正确的做法,还是应该结合所有setState()

【问题讨论】:

  • 我认为有多个设置状态是可以的,因为 React 会在重新渲染之前等待事件处理完成。 stackoverflow.com/questions/33613728/…
  • 您可能想更改标题;如果我的理解是正确的,那么您正在更改该状态中的多个对象,但不会更改该状态中任何对象的内部结构。对我来说,这就是“嵌套”的含义。

标签: reactjs state setstate


【解决方案1】:

您可以像这样更改状态的多个属性。

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

【讨论】:

    【解决方案2】:

    调用多个 setState 是可以的,因为 React 内部会在 setState 之前进行批处理,因此只会调用一次 render。也就是说,您在编写 setState 时出错的可能性很高,因此批处理会忽略更改或设置不正确的值(例如,您可能会根据先前的值为同一个键调用 setState 两次,并且可能期望得到与实际不同的结果你得到)。因此建议您在处理完所有值后调用一次 setState

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

    【讨论】:

    • 为非常有用的信息点赞:Its okay to call multiple setStates since React internally does batching before setState and hence will only call render once.
    【解决方案3】:

    您可以像这样更改状态的多个属性。this.setState({value1: 0, value2: 0})

    【讨论】:

      猜你喜欢
      • 2022-07-01
      • 2018-12-23
      • 2021-04-11
      • 2020-09-23
      • 2021-05-21
      • 1970-01-01
      • 2021-06-26
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多