React hooks: получить состояние useState внутри слушателя - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть это внутри моего компонента:

const [ pendingMessages, setPendingMessages ] = React.useState([]);

React.useEffect(function() {
    ref.current.addEventListener('send-message', onSendMessage);
    return function() {
      ref.current.removeEventListener('send-message', onSendMessage);
    };
  }, []);

function onSendMessage(event) {
  const newMessage = event.message;
  console.log('Here not up to date :(', pendingMessages);
  setPendingMessages([ ...pendingMessages, newMessage ]);
}

Проблема в том, что pendingMessages не обновлен внутри слушателя, потому что он не находится внутри рендера.Это уже прикреплено.Любые идеи, как я могу решить эту проблему?

Спасибо!

1 Ответ

0 голосов
/ 05 февраля 2019

Проблема из-за закрытия, которое формируется при запуске эффекта.Поскольку вы устанавливаете useEffect для запуска только при первоначальном монтировании, он получает значение pendingMessages из замыкания, которое формируется при его объявлении, и, следовательно, даже если pendingMessages обновляется, pendingMessages внутри onSendMessageбудет ссылаться на то же значение, которое присутствовало изначально.

Поскольку вы не хотите получать доступ к значению в onSendMessage и просто обновлять состояние на основе предыдущего значения, вы можете просто использовать шаблон обратного вызова setter

const [ pendingMessages, setPendingMessages ] = React.useState([]);

React.useEffect(function() {
    ref.current.addEventListener('send-message', onSendMessage);
    return function() {
      ref.current.removeEventListener('send-message', onSendMessage);
    };
  }, []);

function onSendMessage(event) {
  const newMessage = event.message;
  setPendingMessages(prevState =>([ ...prevState, newMessage ]));
}
...