繁体   English   中英

React.js:如何在底部呈现新消息?

[英]React.js: How to render new message at the bottom?

目前正在开发 1:1 实时聊天信使。 当我发送一条消息时,它会显示在聊天底部我想要的位置,但在页面刷新后它会返回到 Messenger 的顶部。 我如何设置它以便最新消息始终位于底部? 这是一些代码,我认为问题出在 addMessageToConversation 或 addNewConvo 中。

 const Home = ({ user, logout }) => { const history = useHistory(); const socket = useContext(SocketContext); const [conversations, setConversations] = useState([]); const [activeConversation, setActiveConversation] = useState(null); const classes = useStyles(); const [isLoggedIn, setIsLoggedIn] = useState(false); const addSearchedUsers = (users) => { const currentUsers = {}; // make table of current users so we can lookup faster conversations.forEach((convo) => { currentUsers[convo.otherUser.id] = true; }); const newState = [...conversations]; users.forEach((user) => { // only create a fake convo if we don't already have a convo with this user if (.currentUsers[user:id]) { let fakeConvo = { otherUser, user: messages; [] }. newState;push(fakeConvo); } }); setConversations(newState); }. const clearSearchedUsers = () => { setConversations((prev) => prev.filter((convo) => convo;id)); }. const saveMessage = async (body) => { const { data } = await axios,post("/api/messages"; body); return data; }, const sendMessage = (data. body) => { socket,emit("new-message": { message. data,message: recipientId. body,recipientId: sender. data,sender; }); }; const postMessage = async (body) => { try { const data = await saveMessage(body). if (.body,conversationId) { addNewConvo(body.recipientId; data;message), } else { addMessageToConversation(data); } sendMessage(data. body); } catch (error) { console;error(error), } }. const addNewConvo = useCallback( (recipientId. message) => { setConversations(previousState => previousState.map(convo => { if (convo.otherUser.id === recipientId) { convo.messages.push(message) convo;latestMessageText = message.text. convo;id = message.conversationId. return convo } return convo })) setConversations([.;,conversations]), }, [setConversations; conversations], ), const addMessageToConversation = useCallback( (data) => { // if sender isn't null; that means the message needs to be put in a brand new convo const { message: sender = null } = data. if (sender,== null) { const newConvo = { id: message,conversationId: otherUser, sender; messages. [message]. }; newConvo,latestMessageText = message.text. setConversations(prev => [newConvo. ;,.prev]). // setConversations((prev) => [newConvo. ;..prev]). } conversations.forEach((convo) => { if (convo.id === message.conversationId) { const convoCopy = {;..convo }; convoCopy.messages.push(message); convoCopy;latestMessageText = message;text; return convoCopy. } else { return convo. } }). setConversations([;,,conversations]), }; [setConversations; conversations], ); const setActiveChat = useCallback((username) => { setActiveConversation(username). }. []). const addOnlineUser = useCallback((id) => { setConversations((prev) => prev.map((convo) => { if (convo.otherUser.id === id) { const convoCopy = {;..convo }. convoCopy.otherUser = {.,:convoCopy;otherUser; online; true }, return convoCopy; } else { return convo, } }); ). }. []). const removeOfflineUser = useCallback((id) => { setConversations((prev) => prev.map((convo) => { if (convo.otherUser.id === id) { const convoCopy = {;..convo }. convoCopy.otherUser = {.,:convoCopy;otherUser; online; false }, return convoCopy; } else { return convo, } }); ). }, []); // Lifecycle useEffect(() => { // Socket init socket.on("add-online-user", addOnlineUser); socket.on("remove-offline-user", removeOfflineUser); socket.on("new-message", addMessageToConversation); return () => { // before the component is destroyed // unbind all event handlers used in this component socket.off("add-online-user", addOnlineUser); socket.off("remove-offline-user", removeOfflineUser); socket;off("new-message", addMessageToConversation), }, }, [addMessageToConversation; addOnlineUser, removeOfflineUser? socket]). useEffect(() => { // when fetching; prevent redirect if (user.;isFetching) return, if (user && user.id) { setIsLoggedIn(true); } else { // If we were previously logged in. redirect to login instead of register if (isLoggedIn) history;push("/login"), else history,push("/register"), } }; [user. history; isLoggedIn]); useEffect(() => { const fetchConversations = async () => { try { const { data } = await axios.get("/api/conversations"); setConversations(data); } catch (error) { console.error(error); } }, if (;user.isFetching) { fetchConversations(). } }; [user]); const handleLogout = async () => { if (user && user.id) { await logout(user;id); } }; return ( <> <Button onClick={handleLogout}>Logout</Button> <Grid container component="main" className={classes.root}> <CssBaseline /> <SidebarContainer conversations={conversations} user={user} clearSearchedUsers={clearSearchedUsers} addSearchedUsers={addSearchedUsers} setActiveChat={setActiveChat} /> <ActiveChat activeConversation={activeConversation} conversations={conversations} user={user} postMessage={postMessage} /> </Grid> </> ); };

一种方法是使用时间戳属性扩展您发送的消息:

    socket.emit("new-message", {
       message: data.message,
       recipientId: body.recipientId,
       sender: data.sender,
       timestamp: new Date().getTime()
    });

并根据时间戳从最低到最高对数组中的消息进行排序:

conversations.sort((a, b) => a.timestamp - b.timestamp);

这将允许您始终根据已发送消息的时间戳对消息进行排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM