简体   繁体   English

React JS state 数组在 function 内为空,但项目出现在渲染中

[英]React JS state array empty inside function but items appear in render

I'm writing this react component to render all chats of an user in a chat app.我正在编写此反应组件以在聊天应用程序中呈现用户的所有聊天记录。 The conversation list is acquired from a REST end point and set as a state variable.会话列表是从 REST 端点获取的,并设置为 state 变量。 When a new message arrives through socket, I'm trying to bring the conversation in the list to the top and mark it in a different color.当一条新消息通过套接字到达时,我试图将列表中的对话带到顶部并用不同的颜色标记它。

The code for that looks like the following:该代码如下所示:

const [conversationsList, setConversationsList] = useState([]);

//When a new message arrives, 
const markNewConversation = (message) => {
  console.log(conversationsList); //Empty array
  let newConversationList = conversationsList.map((conversationElement) => {
    if (conversationElement.thread_id === message.thread_id) {
      conversationElement.date_created = message.date_created;
      conversationElement.new_for.push(user._id);
    }
    return conversationElement;
  });
  console.log(newConversationList);
  newConversationList = newConversationList.sortBy(function (o) {
    return o.date_created;
  });
  console.log(newConversationList); //Empty as well.
  setConversationsList(newConversationList); //Whole screen goes black on this.
};

useEffect(() => {
    if (user._id === null) history.push("/");
    connectSocket();
    socket.on("_messageIn", markNewConversation);
    getThreads().then((threads) => {
      threads.forEach((thread, index) => {
        let allParticipants = thread.thread_participants;
        threads[index].other_user = allParticipants.find((participant) => {
          return participant._id != user._id;
        });
      });
      setConversationsList(threads);
      setIsLoading(false);
    });
    // returned function will be called on component unmount
    return () => {
      socket.off("_messageIn", markNewConversation);
    };
  }, []);

return conversationsList.map((conversation) => {
 return(//magically appears inside this div.)
})

The problem is when a new message arrives, the function receives an empty array and the entire screen becomes empty.问题是当一条新消息到达时,function 收到一个空数组,整个屏幕都变空了。 I'm not even setting the array to empty anywhere.我什至没有在任何地方将数组设置为空。 Where am I going wrong?我哪里错了?

In this function you're mutating objects, this can cause weird errors.在这个 function 中,你正在改变对象,这可能会导致奇怪的错误。

let newConversationList = conversationsList.map((conversationElement) => {
if (conversationElement.thread_id === message.thread_id) {
  conversationElement.date_created = message.date_created;
  conversationElement.new_for.push(user._id);
}
return conversationElement;

}); });

it should look like this:它应该是这样的:

let newConversationList = conversationsList.map((conversationElement) =>
     (conversationElement.thread_id === message.thread_id) ? {
         ...conversationElement, 
         date_created: message.date_created,
         new_for: [...conversationElement.new_for, user.id]
    } : { 
        ...conversationElement, 
        new_for: [...conversationElement.new_for]
    }

There is a concept in javascript of State Mutating and we should never mutate the objects directly. State Mutating 的javascript中有一个概念,我们不应该直接对对象进行变异。 Here you are making the mistake is that when new message comes it replaces whole object with new one and kind of re-initialize it.在这里你犯的错误是当新消息到来时它用新消息替换整个 object并重新初始化它。 So spread the state using spread operator before adding new message.所以在添加新消息之前使用传播运算符传播state。 Do like this:这样做:

 let newConversationList = conversationsList.map((conversationElement) =>
     (conversationElement.thread_id === message.thread_id) ? {
         ...conversationElement, //spread/copy like this before mutating
         date_created: message.date_created,
         new_for: [...conversationElement.new_for, user.id]
    } : { 
        ...conversationElement, //spread/copy like this before mutating
        new_for: [...conversationElement.new_for]
    }

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

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