如何在反应中(同时)更改状态的多个属性?
How to change multiple properties of a state in react (at the same time)?
我的主要父组件中有这个状态:
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()
?
您可以像这样更改状态的多个属性。
this.setState({ openedCard: null, offeredChips: 0, activePlayer: nextPlayer });
可以调用多个 setStates,因为 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)
);
您可以像这样更改状态的多个属性。this.setState({value1: 0, value2: 0})
我的主要父组件中有这个状态:
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()
?
您可以像这样更改状态的多个属性。
this.setState({ openedCard: null, offeredChips: 0, activePlayer: nextPlayer });
可以调用多个 setStates,因为 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)
);
您可以像这样更改状态的多个属性。this.setState({value1: 0, value2: 0})