Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pusher implementation in React, losing the context

I'm doing a basic implementation of Pusher, here's the relevant piece:

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]);
    });

}, []);

So, I get the messages from the API and then listen for new messages through Pusher.

The problem I'm having is that inside the callback of pusherChannel.bind, the variable messages is empty, even when it has been filled by the API already.

Maybe the callback sends a copy of messages (and the entire callback function) instead of a reference? Anyways, I don't know how to handle updating the messages using that callback.

I've seen that the bind method can take a third, "context", parameter, but I don't know how to implement it in hooks.

like image 379
Gonzalo Bauer Avatar asked Dec 30 '25 03:12

Gonzalo Bauer


1 Answers

Try this code. I’ve splitted one useEffect to two, add one variable isInit that set to true after fetch init array of messages, add 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]);
like image 108
Kirill Skomarovskiy Avatar answered Jan 05 '26 12:01

Kirill Skomarovskiy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!