正如您在下面的问题中看到的,我收到一条消息,其中包含操作停止。我在那里更新了 3 个状态变量。我的问题是
setTotalScore
。 totalScore
一开始是0,当我收到消息时,我将其更新为与user.score
相同。但是,如果我再次收到该消息,它又会变成 0,尽管它不应该是这样。我到处都读到,这是 useState
更新方式的问题。我真的不知道如何解决这个问题。这是代码:
socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, (payload) => {
const user = payload.find((entry: any) => entry.username == name)
if (user) {
console.log("USER: ", user," USER.SCORE: ", user.score);
console.log("SCORE: ", totalScore);
const addedScore = user.score - totalScore;
setTotalScore(user.score);
setAddedScore(addedScore);
setShowAnswer(true);
}
})
const [totalScore, setTotalScore] = useState<number>(0);
totalScore
应始终更新并等于 user.score
。你可以把它看成totalScore
是user.score
的上一个分数。
这是一个 Javascript 关闭问题,套接字会在渲染周期中的
totalScore
状态值上关闭,其中套接字事件处理程序被实例化并移交给套接字。
您可以使用具有适当依赖关系的
useEffect
来重新封装变量:
React.useEffect(() => {
const stopHandler = (payload) => {
const user = payload.find((entry: any) => entry.username == name);
if (user) {
console.log("USER: ", user," USER.SCORE: ", user.score);
console.log("SCORE: ", totalScore);
const addedScore = user.score - totalScore;
setTotalScore(user.score);
setAddedScore(addedScore);
setShowAnswer(true);
}
};
socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
return () => {
socket.off(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
};
}, [totalScore]);
您还可以使用 React ref 来缓存当前
totalScore
状态值并在处理程序中引用它:
const [totalScore, setTotalScore] = useState<number>(0);
const totalScoreRef = React.useRef(totalScore);
React.useEffect(() => {
totalScoreRef.current = totalScore;
}, [totalScore]);
React.useEffect(() => {
const stopHandler = (payload) => {
const user = payload.find((entry: any) => entry.username == name);
if (user) {
console.log("USER: ", user," USER.SCORE: ", user.score);
console.log("SCORE: ", totalScoreRef.current);
const addedScore = user.score - totalScoreRef.current;
setTotalScore(user.score);
setAddedScore(addedScore);
setShowAnswer(true);
}
};
socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
return () => {
socket.off(`${WsTopic.GAME}/${WsAction.STOP}`, stopHandler);
};
}, []);