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.
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]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With