Sending multiple chat messages at the same time only shows the last message sent

Sending multiple chat messages at the same time only shows the last message sent. Minimal game showing the bug:

The problem seems to be in global-context.js, where the new state is computed from chatMessagesTemp and then passed to the state setter, though a function should be passed instead in this situation.

It should be fixed by changing this

let chatMessagesTemp = [...chatMessages];
if (chatMessagesTemp.length > 50) {
  chatMessagesTemp = chatMessagesTemp.slice(1);
}
setChatMessages([...chatMessagesTemp, { author, message, from, isHtml: isHtml, userId: 1 }]);

to this

setChatMessages(chatMessages => {
  let chatMessagesTemp = [...chatMessages];
  if (chatMessagesTemp.length > 50) {
    chatMessagesTemp = chatMessagesTemp.slice(1);
  }
  return [...chatMessagesTemp, { author, message, from, isHtml: isHtml, userId: 1 }];
});
5 Likes

I’m not sure how it is solving the issue… Can you explain it to me a bit more detail, please :pleading_face:

Hmm, is it a problem of race condition (or critical sections)?
The latter response will keep atomicity within the function, so is it safe?

1 Like

Yes, the problem is that there is a race condition occurring. The state setter may not update the component immediately when called, so passing the state directly to the state setter can result in a delay between when the new state is computed and when the component’s state is actually set to the new state. On the other hand, passing a function which computes and returns the new state to the state setter will ensure that the new state is computed after the delay using the latest state, since the state setter will call the function when it is time to update the state.
Relevant documentation can be found here.

2 Likes

Thanks kyle for the suggestion and report, based on your suggestion the issue should be fixed now.
Let me know if it still occurs.

1 Like