我在react中使用功能组件。
我有一个游戏组件,它是显示父组件。它有一个名为 Main 的父级,其中包含 Game 的所有函数和变量。当我尝试设置特定变量的状态时,我遇到了太多重新渲染错误。它由 startGame() 方法触发,该方法调用 API,然后使用数据调用另一个函数来设置 4-6 个变量。我可以毫无问题地在 6 个变量上使用 setState,但每当我尝试“setPlayers”时,它都会产生太多的重新渲染错误。
我不明白为什么这个变量很特殊。我通过将 Players 切换到常规变量来暂时解决了这个问题,此时我可以毫无问题地为其赋值,但我想了解发生了什么。
Main.jsx
let [isBet, setIsBet] = useState(false);
let [betOptions, setBetOptions] = useState();
let [hasStarted, setHasStarted] = useState(false);
let [id, setId] = useState(0);
const [players, setPlayers] = useState([]) ////The variable that causes the issue
// let players = []; //doesn't cause issue
const [cards, setCards] = useState([])
const [hand, setHand] = useState([])
const [betLog, setBetLog] = useState([])
const [showModal, setShowModal] = useState(false)
const [errorMessage, setErrorMessage] = useState("")
const setVariables= data => {
setHasStarted(true)
setId(data.gameId)
setPlayers(data.users) ///// !!!!! causes too many re-renders bug
// players = data.users // if I use this line instead of the above, the function works
// setPlayers([...data.users])
setHand(data.hand)
console.log("BET OPTIONS", data.betOptions)
if (data.betOptions.name === username){
setBet(data.betOptions)
}
}
const setBet = betOptions => {
setBetOptions(betOptions)
console.log("Your Bet Options are", betOptions)
console.log(betOptions.betAmount)
setIsBet(true)
}
const startGame = async (state) => {
let body = { username,
displayName : state.displayName,
numberOfPlayers : state.numberOfPlayers,
fillWithComputerPlayers: state.fillWithComputerPlayers,
isCustom: state.isCustom,
bigBlind: state.bigBlind
}
try {
const data = await Service.startGame(body);
console.log("response body", data.data)
setVariables(data.data);
} catch (err){
console.error(err)
setErrorMessage(err.message)
setShowModal(true)
setTimeout(function(){
setShowModal(false)
}, (2500))
}
}
所有变量都被子组件 Game 使用。我没有在“玩家”上使用任何 UseEffect,但它是我使用 .map() 的唯一相关变量之一(注意-我也在映射“卡片”并以完全相同的方式设置它,但在不同的功能)。这是“players”变量的唯一用途。
游戏.jsx
let id = props.id;
// let [players] = useState(props.players)
let players = props.players
let hand = props.hand;
let betOptions = props.betOptions;
let cards = props.cards
const [money, setMoney] = useState(0)
const username = props.username;
return (
<div id="background">
/// Lots of other components not relevant to the question
{props.hasStarted ?
<div>
{players.map((v, i) => { /////// !! only use of players
if (v.username !== username){
return (
<PlayerInfo name={v.username} money={v.money} key={i} class="info" />
)
} else {
setMoney(v.money)
}
})}
{cards.length > 0 && cards.map((v, i) => {
return (
<img className="cards" key={i} src={process.env.PUBLIC_URL + '/pics/PNG/' + v.image} alt={v.image} />
)
})}
<div id="my">
<MyInfo name={username} money={money} hand={hand} class="info" />
</div>
</div>
:
<SettingsForm startGame={props.startGame} username={username} />
}
</div>
<Log betLog={props.betLog} />
</div>
PlayerInfo.jsx
import "./Info.css"
const PlayerInfo = props => {
return (
<div className="info">
<h4>{props.name}</h4> {props.money}$
<div>
<img className="cards" src={process.env.PUBLIC_URL + '/pics/PNG/red_back.png'} alt="card" />
<img className="cards" src={process.env.PUBLIC_URL + '/pics/PNG/red_back.png'} alt="card" />
</div>
</div>
);
}
export default PlayerInfo;
最佳答案
为什么不将尽可能多的有意义的对象转变为 1 个或多个对象?
与 setState
不同,它会导致 5 次单独的重新渲染,
将状态设置为包含所有这 5 个部分的 1 个对象只会导致 1 次重新渲染。
关于reactjs - setState 的问题和太多的重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69065541/