2020年12月19日星期六

React native: Flatlist does not update instantly when i send a message

I just finishing setting up my socket in my react native and nodejs project and still my flatlist does not update instantly when a message is sent, i need to refresh the app in order for it to update.

I thought that by using socket this will work but still it is not working. whenever i user opens a chat i get eg. user: 1 has joined conversation 1 in the console which indicates that the socket is working.

Client Side

function ChatScreen({route,navigation}) {  const message = route.params.message;    const [messages, setMessages] = useState(message.Messages);  const [text, setText] = useState('');  const [socket, setSocket] = useState(null);  const { user } = useAuth();    const index = route.params.index;  const updateView = route.params.updateView;    useEffect(() => {  const newsocket =io.connect(socketURL)  setMessages(messages);  newsocket.on('connect', msg => {      console.log(`user: ${user.id} has joined conversation ${message.id}`)      setMessages(messages=>messages.concat(msg))      setSocket(newsocket)   });   return()=>newsocket.close;   }, []);    const onSend = (ConversationId,senderId,receiverId,message) => {    messagesApi.sendMessage({ConversationId,senderId,receiverId,message});  setText("")    const to = (user.id===route.params.message.user1?   route.params.message.user2:route.params.message.user1)    socket.emit('message', { to: to, from: user.id, message, ConversationId });  };    const updateText=(text)=>{  setText(text);  }    return (      <FlatList      inverted      data={message.Messages}      keyExtractor={(message) => message.id.toString()}      renderItem={({item,index})=>(          <>          <Text>           {moment(item.createdAt).fromNow()}           </Text>          <MessageBubble          text={item.message}          mine={item.senderId !== user.id}          />           </>      )}            />      <View style={styles.messageBoxContainer}>          <TextInput           onChangeText={updateText}           value={text}           />          <TouchableOpacity             onPress={()=>{onSend(message.id,user.id,(user.id===message.user1?             message.user2:message.user1),text)}}>          </TouchableOpacity>      </View>  );  }  

Server Side

const express = require("express");  const app = express();  const http = require("http");  const socket = require("socket.io")  const server=http.createServer(app);  const io =socket(server)    io.on('connection', (socket) => {  console.log("connected")  socket.on('message', (data) => {  console.log(data)    socket.join(data.ConversationId);    io.sockets.in(data.to).emit('send_message', { message:     data.message, to: data.to });    });    });  

UPDATE

Client Side

  const message = route.params.message;    const [messages, setMessages] = useState([]);    const [text, setText] = useState('');    const [socket, setSocket] = useState(null);    const { user } = useAuth();      useEffect(() => {    const newsocket =io.connect("http://192.168.1.103:9000")    newsocket.on('connect', msg => {    console.log(`user: ${user.id} has joined conversation     ${message.id}`)    setSocket(newsocket)    setMessages(message.Messages)    });      newsocket.on("send_message", (msg) => {    console.log("this is the chat message:", msg);    setMessages([ { ...message.Messages },...messages]);    });      return()=>newsocket.close;    }, []);      const onSend = (ConversationId,senderId,receiverId,message) => {    console.log("sent")  messagesApi.sendMessage({ConversationId,senderId,receiverId,message});  setText("")  const to = (user.id===route.params.message.user1?   route.params.message.user2:route.params.message.user1)      socket.emit(      'message', { to: to, from: user.id, message,ConversationId });    };     const updateText=(text)=>{   setText(text);   }    <FlatList      inverted      data={messages}      keyExtractor={(message) => message.id.toString()}      renderItem={({item,index})=>(          <>          <Text>           {moment(item.createdAt).fromNow()}           </Text>          <MessageBubble          text={item.message}          mine={item.senderId !== user.id}          />           </>      )}         bounces={false}        />      <View style={styles.messageBoxContainer}>          <TextInput           onChangeText={updateText}           value={text}           />          <TouchableOpacity            onPress={()=>{           onSend(           message.id,           user.id,            (user.id===message.user1?message.user2:message.user1),           text           )}}           >           <Text>Send</Text>          </TouchableOpacity>       </View>  

Server Side

io.on('connection', (socket) => {  console.log("connected")  socket.on('message', (data) => {  console.log(data)  socket.emit('send_message', { message: data.message, receiverId:   data.to,senderId:data.from,conversationId:data.ConversationId })  });  });  

Using the updated code, when i open a chat i get

user: 43 has joined conversation 4 ---- on client side console  connected ---- on server side console  

Using the updated code, when i send a message i get

this is the chat message: Object {  "conversationId": 25,  "message": "You",  "receiverId": 47,  "senderId": 43,  } --- in my client side console    { to: 47, from: 43, message: 'You', ConversationId: 25 } ---- server   side console  

But then i get an error

undefined is not an object (evaluating 'message.id.toString')  

I think my problem is that i am not emitting the the message id correctly and therefore my flatlist does not know it. To get a message id, i need to store the message in db first

NEW UPDATE

Client Side

  const message = route.params.message;    const [messages, setMessages] = useState([]);    const [text, setText] = useState('');    const [socket, setSocket] = useState(null);    const { user } = useAuth();      useEffect(() => {    const newsocket =io.connect(socketURL)    newsocket.on('connect', msg => {    console.log(`user: ${user.id} has joined conversation     ${message.id}`)    setSocket(newsocket)    setMessages(message.Messages)    });      newsocket.on("send_message", (msg) => {    console.log("this is the chat message:", msg);    const data = [...messages];     console.log(data)    data.push(msg);    setMessages(data);     });      return(()=>newsocket.close());    }, []);      const onSend = (ConversationId,senderId,receiverId,message) => {    console.log("sent")  messagesApi.sendMessage({ConversationId,senderId,receiverId,message});  setText("")  const to = (user.id===route.params.message.user1?   route.params.message.user2:route.params.message.user1)      socket.emit(      'message', { to: to, from: user.id, message,ConversationId });    };     const updateText=(text)=>{   setText(text);   }    <FlatList      inverted      data={messages}      keyExtractor={(item,index)=>index.toString()}      renderItem={({item,index})=>(          <>          <Text>           {moment(item.createdAt).fromNow()}           </Text>          <MessageBubble          text={item.message}          mine={item.senderId !== user.id}          />           </>      )}         bounces={false}        />      <View style={styles.messageBoxContainer}>          <TextInput           onChangeText={updateText}           value={text}           />          <TouchableOpacity            onPress={()=>{           onSend(           message.id,           user.id,            (user.id===message.user1?message.user2:message.user1),           text           )}}           >           <Text>Send</Text>          </TouchableOpacity>       </View>  

Server Side

io.on('connection', (socket) => {  console.log("connected")  socket.on('message', (data) => {  console.log(data)  socket.emit('send_message', { message: data.message, receiverId:   data.to,senderId:data.from,conversationId:data.ConversationId })  });  });  

Now using the new updated code when i send a message only the new message gets rendered to the sender without the previous messages, and the receiver does not receive anything while on the chat.

https://stackoverflow.com/questions/65325432/react-native-flatlist-does-not-update-instantly-when-i-send-a-message December 16, 2020 at 10:40PM

没有评论:

发表评论