我应该如何在不破坏渲染项目顺序的情况下映射两个数组?
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) {
//
}
}
})}
我正在尝试创建一个具有一些附加功能(例如发送和接收语音音频)的聊天机器人。我使用了两种不同的数组状态来呈现文本消息和音频消息。在渲染部分,我分别映射这些数组。
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) {
//
}
}
})}