javascript - React 何时渲染——管理各种异步调用、socketIO 和 React 之间的状态的问题
问题描述
我正在开发一个以 React 作为前端的 MERN 堆栈应用程序。这是一款依靠 socketIO 知道其他玩家何时移动的游戏,以便游戏可以从数据库执行 REST API 调用以允许 React 刷新游戏板。
它工作得很好,但每隔一段时间,React 应用程序似乎都没有收到 socketIO 消息,尽管据我了解,socketIO 保证交付。这是一个很难重现的错误。一个想法是 React 可能会在消息到达时进行刷新,这会以某种方式把事情搞砸。所以我添加了一个标志,true
当消息到达时设置为,并在更新游戏加载时清除标志,我将它放入 Reactstate
中,导致(我希望)刷新。奇怪的是,render
在 flag 静止时被调用true
。这是为什么?
在伪代码中
this.state = game
updateFlag = false
onSocketMessage => {
updateFlag = true
asyncGetNewGame
.then(game => {
updateFlag = false
this.setState({game})
})
}
render() {
log.debug(updateFlag) // is true, but why?
const {state:{game}} = this
<SomeComponent game={game}>
}
如上所述,标志true
在渲染期间仍然存在,但我认为在false
异步调用之后获取新游戏的标志的同步设置将在渲染之前发生,因为据我所知,渲染是由对state
field的更改game
,直到我更改标志后才设置。
我是否正确理解了时间表?如果有人可以帮助阐明这一点,我将不胜感激。
解决方案
好吧,setState
它不是一个同步方法,因此,之前对它的任何调用都可能触发渲染,不一定是onSocketMessage
. 此外,对组件道具的修改可能会导致重新渲染。如果您想遵循同步逻辑,updateFlag
我建议您使用回调:setState(value, callback)
。
另外,请注意这里的声明:
除非 shouldComponentUpdate() 返回 false,否则 setState() 将始终导致重新渲染。如果正在使用可变对象并且在 shouldComponentUpdate() 中无法实现条件渲染逻辑,则仅在新状态与先前状态不同时调用 setState() 将避免不必要的重新渲染。
因此,如果您的逻辑依赖于渲染,那么它可能是错误的,因为其他事情可能会触发重新渲染。是的,socket.io 保证数据包/消息的传递,但它不保证其他因素,例如您的逻辑、网络状态/配置都很好。如果出现问题,我建议您使用套接字客户端和服务器检查错误事件。
此外,如果您的逻辑依赖于特定的状态/道具值更改,那么您应该使用componentDidUpdate进行验证。
希望我能帮上忙。
推荐阅读
- python - 二叉树不显示节点存在 Python
- css - 返回几个元素的父选择器
- php - 如何在一个php中显示两个数据表?但它只出来一个表记录
- c++ - 当我们写 for(;;) 时它会做什么?for 循环中的双分号有什么作用?
- vcpkg - 构建端口时获取 VCPKG 以在包含路径中包含 VCPKG 包含目录
- swift - 从片段中获取 func 占位符值以在顶级代码级别点击选项卡后显示
- javascript - 为什么在 useEffect 挂钩中使用 useContext 时,用 useRef 包装 useContext 不会给出任何警告以将其添加为依赖项?
- django - django+celery+redis,应用程序。控制。检查 ()
- python - 我编写这段代码是为了在 PYTHON 中制作一个没有 GUI 的井字游戏
- html - 尝试使用 VBA 抓取 Freddie Mac 网站