【问题标题】:How to setState from within a callback?如何从回调中设置状态?
【发布时间】:2020-11-25 05:52:39
【问题描述】:

我正在尝试将 Twilio 的聊天客户端 SDK(文档不足)与 React Hooks/FC 一起使用。并且在从 on 回调的上下文中找到更新我的状态的正确方法时遇到问题。

http://media.twiliocdn.com/sdk/js/chat/releases/4.0.0/docs/

如果我在每次渲染时都注册它,那么我自然会遇到内存泄漏和重复响应处理。

const MessageList = ({channel}) => {
  const [messageGroups, setMessageGroups] = React.useState([]);

  ...

    channel.on("messageAdded", (message) => {
    if(messageGroups.length == 0) {
      setMessageGroups([[message]])
      return
    }

    let messageChucks = [...messageGroups]

    ...

    setMessageGroups(messageChucks)
  })

如果我在useEffect 中注册它,则messageGroups 的值静态定义为上次触发useEffect 时的值,这意味着messageGroups 重置为空。然后我可以更新我的useEffect 以在MessageGroups 更改时重新注册,但这只会导致更慢的内存泄漏。

const MessageList = ({channel}) => {
  const [messageGroups, setMessageGroups] = React.useState([]);

  ...

  React.useEffect(() => {
    channel.on("messageAdded", (message) => {
      if(messageGroups.length == 0) {
        setMessageGroups([[message]])
        return
      }

      let messageChucks = [...messageGroups]

      ...
 
      setMessageGroups(messageChucks)
    })
  }, [channel])

有没有办法让我注册的回调使用最新状态,或者其他解决这个问题的方法?

【问题讨论】:

  • 对事件的订阅应该只发生一次。但是在这里,每次更新channel 时都会调用useEffect。你可以尝试用[] 替换[channel] 吗?
  • 频道改变时需要重新注册,现在为零。问题是在它注册后,messageGroups 的上下文不会在重新渲染后更新,即使它已经填充了历史记录

标签: reactjs react-hooks twilio twilio-api react-functional-component


【解决方案1】:

好的,所以答案是将函数传递给setState,它会为您提供先前的状态,然后您可以更新状态并返回它。

  const handleMessageAdded = (message) => {
    setMessageGroups(prevMessageGroups => {
      if(prevMessageGroups.length == 0) {
        return [[message]]
      }

      let messageChucks = [...prevMessageGroups]

      ...

      return messageChucks
    })
  }

  React.useEffect(() => {
    channel.on("messageAdded", handleMessageAdded)
  }, [channel])

【讨论】:

    猜你喜欢
    • 2020-08-27
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2020-03-24
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    相关资源
    最近更新 更多