我有一个具有某些聊天功能的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中发起的更改?
答案 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;
})
}
}