react-native-chat-ui icon indicating copy to clipboard operation
react-native-chat-ui copied to clipboard

User2 messages disappear once User1 replies; setState going wrong?

Open tbergeron opened this issue 3 years ago • 2 comments

In the following example, User2's messages are getting erased from the state as soon as the User1 sends a message.

I'm persuaded it's a React setState mistake but I've followed the react-native-chat-ui's docs as much as possible but somehow there is something going wrong and I cannot put my finger on it.

To test, just type a message and wait 1 second for the User2 to reply and you'll see that as soon as the User2 replies, the User1's messages disappear.

What's weird is that the User2's messages persist which boggles my mind and makes me think it might be related to the project and not only a React setState mistake. (I thought maybe I don't wait for setState to be done executing but this doesn't seem to be the case)

I've been scratching my head for a hour on this so I thought I'd ask here.

Here is a video of the bug in action: https://streamable.com/rxbx18

Anybody has an idea?

Amazing project by the way!

Thanks!

import React, { useEffect, useState } from 'react';
import { Chat, MessageType } from '@flyerhq/react-native-chat-ui'
import { SafeAreaProvider } from 'react-native-safe-area-context'

const uuidv4 = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = Math.floor(Math.random() * 16)
    const v = c === 'x' ? r : (r % 4) + 8
    return v.toString(16)
  })
};

const user    = { id: uuidv4(), firstName: 'User1' };
const chatbot = { id: uuidv4(), firstName: 'User2' };

const App = () => {
  const [messages, setMessages] = useState<MessageType.Any[]>([])

  const addMessage = (message: MessageType.Any) => {
    setMessages([message, ...messages]);
  };

  const handleSendPress = (message: MessageType.PartialText) => {
    // display user message
    const textMessage: MessageType.Text = {
      author   : user,
      createdAt: Date.now(),
      id       : uuidv4(),
      text     : message.text,
      type     : 'text',
    };
    addMessage(textMessage);

    // display bot message
    // NOTE: adding a timeout so that you can see user's message for a second...
    setTimeout(() => {
      const chatbotTextMessage: MessageType.Text = {
        author   : chatbot,
        createdAt: Date.now(),
        id       : uuidv4(),
        text     : `Response that will erase user's messages...`,
        type     : 'text',
      };
      addMessage(chatbotTextMessage);
    }, 1000);
  };

  return (
    <SafeAreaProvider>
    <Chat
      messages={messages}
      showUserNames={true}
      onSendPress={handleSendPress}
      user={user}
    />
  </SafeAreaProvider>
  );
}

export default App;

tbergeron avatar Dec 28 '22 12:12 tbergeron

I fixed it by doing:

setMessages(prev => [message, ...prev])

instead of doing what was suggested in the docs:

setMessages([message, ...messages]);

I guess it'd be a good idea to change the documentation? I'm surprised nobody got that issue before.

tbergeron avatar Dec 28 '22 12:12 tbergeron

Since I am unable to properly maintain this library atm I think it has close to 0 usage :) will reopen just in case if I return to check this

demchenkoalex avatar Dec 31 '22 00:12 demchenkoalex