【发布时间】:2021-02-17 14:52:45
【问题描述】:
当新用户访问页面时,他们可以填写一个用户名,该用户名存储在 state 和 cookie 中。我稍后想访问该 cookie 和状态以在游戏会话中识别用户名,但是它们此时都是空的,即使我知道它们已被设置(日志记录会看到值,用户名正确显示在标题中)。为什么会这样?
const [cookies, setCookie] = useCookies(["username"]);
const [formerUsername, setFormerUsername] = useState(cookies.username ? cookies.username : null);
...
function handleUsernameChange(username) {
setCookie("username", username, {path: "/", expires: expirationDate});
setFormerUsername(username);
...
}
useEffect(() => {
...
socket.on(TRANSMISSIONS.startGame, data => {
let playerIndex = data.room.players.indexOf(cookies.username);
history.push({pathname: "/game", data: {username: cookies.username, room: data.room, playerIndex: playerIndex,
}});
});
播放器索引为 -1,因为 cookies.username 未定义。我知道它已设置,因为我 a) 看到 cookie,b) 在页面标题中看到从 cookie 加载的用户名。
那么为什么这里显示为未定义呢? useState 也是如此,它显示的是初始值 (null),而不是实际值...
编辑:完整代码在这里 - https://github.com/faire2/loreHunters/blob/master/src/components/loginPage/LoginPage.js
代码位于 arnak-dev.herokuapp.com。
【问题讨论】:
-
“当一个新用户访问页面时,他可以填写一个用户名” - 如果你的访问者是女性怎么办?
-
如果您使用效果来简单地将更改记录到
cookies,您是否看到它在您的组件中更新?你能包括一个更完整的组件示例吗?socket的作用是什么all?我怀疑您已经在startGame回调中关闭了您的cookies值。 -
cookies.username在您useState(cookies.username ? cookies.username : null);时尚未定义,并且您的useEffect在组件挂载时仅运行一次。当cookies状态更新时,您无法更新任何套接字详细信息。 -
好吧,我认为你有一些问题。首先,是的,看起来您已经在
socket事件处理程序中关闭了初始cookies状态,因为useEffect有一个空的依赖数组。其次,在您调用的几个函数中setCookie但随后一两行发出 currentcookie.username值(不是刚刚排队等待 下一个渲染周期)。第三,(我猜与第一个相关)你的效果不会返回清理函数来(A)断开/关闭任何打开的套接字和(B)重新封闭更新的cookies状态值事件处理程序。 -
在您导航到新路由之前,套接字需要保持打开状态,或者至少取消注册登录页面组件添加的事件处理程序。您可能希望通过返回的清理功能获得安装效果。我认为要解决
cookies值的主要问题,您需要定义 depend 在效果挂钩外部的cookies的套接字回调。如果你愿意,我可以提供一个例子作为答案。
标签: reactjs cookies use-effect use-state