Реализация Pusher в React, теряя контекст - PullRequest
1 голос
/ 03 августа 2020

Я делаю базовую c реализацию Pusher, вот соответствующая часть:

const [messages, setMessages] = useState();

useEffect(() =>
{
    //Fetching the messages from the API
    fetchMessages().then(fetchedMessages => setMessages(fetchedMessages));

    //Subscribing to a Pusher event in case of new messages
    pusherChannel.bind(EVENT_MESSAGE_SENT, (data) => 
    {
        //Here, "messages" is empty, even when it has been filled by the API already
        setMessages([...messages, data.message]);
    });

}, []);

Итак, я получаю сообщения от API, а затем прослушиваю новые сообщения через Pusher.

Проблема, с которой я столкнулся, заключается в том, что внутри обратного вызова pusherChannel.bind переменная messages пуста, даже если она уже была заполнена API.

Возможно, обратный вызов отправляет копия messages (и всей функции обратного вызова) вместо ссылки? В любом случае, я не знаю, как обрабатывать обновление сообщений с помощью этого обратного вызова.

Я видел, что метод bind может принимать третий, «контекстный» параметр, но я не знаю, как это реализовать в хуках.

1 Ответ

0 голосов
/ 03 августа 2020

Попробуйте этот код. Я разделил один useEffect на два, добавил одну переменную isInit, для которой установлено значение true после получения массива сообщений инициализации, добавил useCallback.

const [messages, setMessages] = useState();
const [isInit, setIsInit] = useState(false);
const handleMessageSent = useCallback((data) => {
  setMessages(prevState => ([...prevState, data.message]));
}, []);

useEffect(() => {
  fetchMessages().then((fetchedMessages) => {
    setMessages(fetchedMessages);
  }).finally(() => {
    setIsInit(true);
  });
}, []);

useEffect(() => {
  if (!isInit) {
    return;
  }

  pusherChannel.bind(EVENT_MESSAGE_SENT, handleMessageSent);

  return () => {
    pusherChannel.unbind(EVENT_MESSAGE_SENT, handleMessageSent);
  };
}, [isInit, handleMessageSent]);
...