React无法正确管理回调的状态

时间:2020-02-13 02:13:40

标签: reactjs react-native react-hooks

我有一个具有某些聊天功能的React Native应用程序。管道似乎连接良好,但是状态管理发生了一些奇怪的事情。我的状态管理是使用钩子设置的。这是管理更新的代码:

      console.log(
        'MESSAGES -()- ::',
        messages.map(m => m.text),
      )

      const gotChatEntity = (entity: MessageOrStatement) => {
        if (isMessage(entity)) {
          let mutableMessages = [...messages]
          console.log(
            'MUTABLE MESSAGES -(BEFORE)- ::',
            mutableMessages.map(m => m.text),
          )
          mutableMessages.push(entity)
          console.log(
            'MUTABLE MESSAGES -(AFTER)- ::',
            mutableMessages.map(m => m.text),
          )
          setMessages(mutableMessages)
        }
      }
每当套接字管道上通过聊天消息时,就会触发

gotChatEntity。它似乎正在按预期方式触发,但请查看我收到的日志消息。以下是上述代码的两次后续执行的日志消息。

 LOG  MUTABLE MESSAGES -(BEFORE)- :: ["I got the beets", "how many you want?", "1"]
 LOG  MUTABLE MESSAGES -(AFTER)- :: ["I got the beets", "how many you want?", "1", "2"]
 LOG  MESSAGES -()- :: ["I got the beets", "how many you want?", "1", "2"]
 LOG  MUTABLE MESSAGES -(BEFORE)- :: ["I got the beets", "how many you want?", "1"]
 LOG  MUTABLE MESSAGES -(AFTER)- :: ["I got the beets", "how many you want?", "1", "3"]
 LOG  MESSAGES -()- :: ["I got the beets", "how many you want?", "1", "3"]

请注意,聊天消息2在第二条日志中是如何不在列表中!发生了什么事?

可能值得注意的是,消息状态处理的另一端按预期工作。当用户发送时,一条消息非常有用。这是代码

const sendMessage = (text: string) => {
    let message = client.sendMessage(text)
    let mutableMessages = [...messages]
    mutableMessages.push(message)
    setMessages(mutableMessages)
  }

在那里管理状态没有问题! React是否会有某种怪异的东西不会更新钩子以响应未在UI中发起的更改?

1 个答案:

答案 0 :(得分:1)

这里可能发生的情况是,由于setState的异步性质,gotChatEntity连续两次触发时,两者都以相同的原始消息状态执行(第二个消息是在重新渲染状态之前执行的)第一次通话发生。)

另一个可能的原因是,gotChatEntity的钩子以useEffect的方式设置了componentDidMount,这会创建一个仅显示初始消息状态的闭包。

无论哪种情况,要解决此问题,您都需要使用带有回调的setState来检索最新消息。


const gotChatEntity = (entity: MessageOrStatement) => {
    if (isMessage(entity)) {
        setMessages(oldMessages => {
            let mutableMessages = [...oldMessages]
            console.log(
                'MUTABLE MESSAGES -(BEFORE)- ::',
                mutableMessages.map(m => m.text),
            )
            mutableMessages.push(entity)
            console.log(
                'MUTABLE MESSAGES -(AFTER)- ::',
                mutableMessages.map(m => m.text),
            )
            return mutableMessages;
        })
    }
}