首页 > 解决方案 > 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异步调用之后获取新游戏的标志的同步设置将在渲染之前发生,因为据我所知,渲染是由对statefield的更改game,直到我更改标志后才设置。

我是否正确理解了时间表?如果有人可以帮助阐明这一点,我将不胜感激。

标签: javascriptreactjs

解决方案


好吧,setState它不是一个同步方法,因此,之前对它的任何调用都可能触发渲染,不一定是onSocketMessage. 此外,对组件道具的修改可能会导致重新渲染。如果您想遵循同步逻辑,updateFlag我建议您使用回调:setState(value, callback)

另外,请注意这里的声明

除非 shouldComponentUpdate() 返回 false,否则 setState() 将始终导致重新渲染。如果正在使用可变对象并且在 shouldComponentUpdate() 中无法实现条件渲染逻辑,则仅在新状态与先前状态不同时调用 setState() 将避免不必要的重新渲染。

因此,如果您的逻辑依赖于渲染,那么它可能是错误的,因为其他事情可能会触发重新渲染。是的,socket.io 保证数据包/消息的传递,但它不保证其他因素,例如您的逻辑、网络状态/配置都很好。如果出现问题,我建议您使用套接字客户端和服务器检查错误事件。

此外,如果您的逻辑依赖于特定的状态/道具值更改,那么您应该使用componentDidUpdate进行验证。

希望我能帮上忙。


推荐阅读