我应该如何在不破坏渲染项目顺序的情况下映射两个数组?

How should I map over two arrays without ruining the order of rendered items?

我正在尝试创建一个具有一些附加功能(例如发送和接收语音音频)的聊天机器人。我使用了两种不同的数组状态来呈现文本消息和音频消息。在渲染部分,我分别映射这些数组。

setMessageList((prevlist) => [...prevlist, {id: uuidv4(), message: currentMessage, type: "sender",}, {id: uuidv4(), message: "response.data.data.answer", type:"reciever"}]);


     setAudioList(prevState => [
      ...prevState,
      {id: uuidv4(), audio: audioUrlQuestion, type: "sender", isLoading: isLoadedVoice} , 
      {id: uuidv4(), audio: result.data.filePath , type: "reciever", isLoading: isLoadedVoice}
    ])
 {audioList.map(item => {
            if (item.type === "sender") {
                   //render sender audio tag
            }
            if (item.type === "reciever" && isLoadedVoice === false) {
              // ...
            } else if (item.type === "reciever" && isLoadedVoice === true) {
              //
            }
          })}
          {messageList.map((item) => {
            if (item.type === "sender") {
              //show sender messages
            }
            if (item.type === "reciever" && isLoadedMessage === false) {
               // show received mesgs
            
            } else if (item.type === "reciever" && isLoadedMessage === true) {
              //
            }
          })}

但是,只有当用户发送 audio/text 消息而不进行任何切换时,一切才能按正确的顺序进行。例如,如果您的第一条消息是音频,第二条是文本,当您想要再次发送第三条音频类型的消息时,它应该在文本消息之后显示音频。但事实并非如此。相反,它会出现在第一条音频消息之后(在文本消息之前)。
那么,如何才能按正确的顺序依次呈现语音消息和文本消息?

这是简单的方法,

const audio = [{
    message: "Audio 1",
    time: 1
  },
  {
    message: "Audio 1",
    time: 3
  },
];
const message = [{
  mesage: "Text 1",
  time: 2
}];
[...audio,...message].sort(( a, b )=> {
  if ( a.time < b.time ){
    return -1;
  }
  if ( a.time > b.time ){
    return 1;
  }
  return 0;
}).map((item)=> console.log(item))

它要么排序(约束:每个渲染的 ~nlogn 复杂性,需要时间戳),要么将它们放在同一个状态数组中,即

const [allMessages, setAllMessages] = useState([]);

...

setAllMessages([...allMessages, {type: "audio", item: {id: uuidv4(), audio: audioUrlQuestion, type: "sender", isLoading: isLoadedVoice}}, {type: "audio", item: 
      {id: uuidv4(), audio: result.data.filePath , type: "reciever", isLoading: isLoadedVoice}}]);

...

setAllMessages([...allMessages, {type: "text", item: {id: uuidv4(), message: currentMessage, type: "sender",}}, {type: "text", item: {id: uuidv4(), message: "response.data.data.answer", type:"reciever"}}]);

...

 {allMessages.map(({type, item}) => {
           if (type === "audio") {
if (item.type === "sender") {
                   //render sender audio tag
            }
            if (item.type === "reciever" && isLoadedVoice === false) {
              // ...
            } else if (item.type === "reciever" && isLoadedVoice === true) {
              //
            }
           } else if (type === "text") { 
if (item.type === "sender") {
              //show sender messages
            }
            if (item.type === "reciever" && isLoadedMessage === false) {
               // show received mesgs
            
            } else if (item.type === "reciever" && isLoadedMessage === true) {
              //
            }
           }
            
          })}