Как установить состояние из обратного вызова? - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь использовать SDK клиента чата Twilio, который недостаточно документирован, с React Hooks / F C. И у меня возникла проблема с поиском правильного способа обновления моего состояния из контекста обратного вызова 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])

Есть ли способ, чтобы мой обратный вызов был зарегистрирован, используя последнее состояние, или другой способ обойти это?

1 Ответ

1 голос
/ 06 августа 2020

Хорошо, поэтому ответ - передать функцию в setState, который дает вам предыдущее состояние, а затем позволяет обновить состояние и вернуть его.

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

      let messageChucks = [...prevMessageGroups]

      ...

      return messageChucks
    })
  }

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