React useState 和 useEffect 混淆
Posted
技术标签:
【中文标题】React useState 和 useEffect 混淆【英文标题】:React useState & useEffect confusion 【发布时间】:2022-01-12 00:29:29 【问题描述】:我对使用 React 功能组件实现某些东西有些困惑。我知道 useState 是异步的,并且在改变状态后读取时不会反映该值。但是我不知道如何实现我正在尝试做的事情。基本上在我的 React 组件中,当它挂载时,我通过 websocket 连接向服务器询问一些后端信息并将其设置为状态。执行此操作后,我立即执行基于开关的方法,但是我无法访问该方法中的状态,因为我刚刚改变了状态并且因为它是异步的,所以更改不会直接反映。这是我的代码:
useEffect(() =>
socket.emit("crash:info", (resp) =>
const status, gameId, gameHistory, mockVariable = resp;
setGameId(gameId);
setGameHistory(gameHistory);
setStatus(status);
switch (status)
case 2:
handleGameEnd( variable: mockVariable );
break;
);
, []);
const handleGameEnd = function (data)
//other code with this variable...
const variable = data;
//here is the issue; gameId is undefined because it is not set by the state yet because setState is async
if (gameHistory.filter((game) => game.gameId === gameId).length > 0)
return;
setGameHistory((gameHistory) =>
const newGameHistory = [...gameHistory];
newGameHistory.unshift( gameId: gameId );
newGameHistory.pop();
return newGameHistory;
);
;
有人有想法吗?
【问题讨论】:
你能把相关数据(即gameId
作为参数传递给这个函数吗?variable
从未使用过。我推荐minimal reproducible example。
@ggorlen 我添加了变量作为示例,因为此处需要其他数据,而本示例不需要这些数据。我添加它是为了清楚地表明这个函数接受变量。但是是的,我可以将 gameId 作为参数传递给这个函数。
我会考虑将你的前两行从 useEffect 中取出并放入它自己的钩子中。从那里您可以保留 useEffect 来设置所有状态变量,并将 resp
变量放在 useEffect 的依赖数组中。
@Steve 我不太明白你的意思,你能给出一个代码方面的例子吗?
"但是是的,我可以将gameId
作为参数传递给这个函数。" ——那么问题就解决了吗?
【参考方案1】:
反应就像我在跟你开玩笑一样,为什么你要设置两次 gameHistory 状态,你可以做你所有的逻辑,然后像这样在最后调用所有 setStates
useEffect(() =>
socket.emit("crash:info", (resp) =>
const status, gameId, gameHistory, mockVariable = resp;
switch (status)
case 2:
handleGameEnd( variable: mockVariable, gameId, gameHistory );
break;
setStatus(status);
setGameId(gameId);
// you already set gameHistory no need for that
//setGameHistory(gameHistory);
);
, []);
const handleGameEnd = function (data)
//other code with this variable...
const variable, gameId, gameHistory = data;
//now you have both gameId and gameHistory
if (gameHistory.filter((game) => game.gameId === gameId).length > 0)
return;
setGameHistory((gameHistory) =>
const newGameHistory = [...gameHistory];
newGameHistory.unshift( gameId: gameId );
newGameHistory.pop();
return newGameHistory;
);
// you can either setState here
setGameId(gameId);
setGameHistory(gameHistory);
// or back to useEffect block
;
【讨论】:
以上是关于React useState 和 useEffect 混淆的主要内容,如果未能解决你的问题,请参考以下文章