I'm working on a Messagelist component in which I am pulling message data from an external API. Every message contains a UserId in which I'll use to query my own API for more user information. I put the list of foundUsers in my redux store and have connected my component. Before rendering to the DOM, my objective is to loop through each individual message and replace the userid with the name of its corresponding user.
The problem I'm having is that the loop does not appear to finish before rendering the component, giving me some strange behavior.
Half a second later
Here is my code:
render(){
let users = this.props.chatkit.roomUsers
let userIds = users.map((user) => {
return user.id
})
let roomMessages = this.props.messages
let messages = []
for(var i = 0; i < roomMessages.length; i++){
//create a new field to give each message a unique id
roomMessages[i].unique = roomMessages[i].senderId
//create a new field to give each message the avatar from that user
let matchingUserIndex = userIds.indexOf(roomMessages[i].senderId)
if(matchingUserIndex >= 0){
roomMessages[i].avatar = users[matchingUserIndex].avatar
}
//review messages
let previous = {}
if(i > 0){
previous = roomMessages[i - 1]
}
let currentMessage = roomMessages[i]
//check if consecutive messages are made by the same user
if(currentMessage.senderId === previous.senderId && currentMessage.unique === previous.unique){
//display user name and avatar as an empty string
messages.push({...currentMessage, unique: "", avatar: ""})
} else{
//display the user name
messages.push({...currentMessage})
}
}
//transform the unique field to contain the name of the user
let updatedMessages = []
for(var j = 0; j < messages.length; j++){
let matchingIdIndex = userIds.indexOf(messages[j].unique)
if(matchingIdIndex >= 0 && messages[j].unique !== ""){
messages[j].unique = users[matchingIdIndex].name
updatedMessages.push(messages[j])
} else {
updatedMessages.push(messages[j])
}
}
let currentChatkitUser = this.props.chatkit.chatUser.id
return(
<div>
{this.props.room && (
<div
style={{overflow: "scroll", overflowX: "hidden", maxHeight: "70vh"}}
ref={this.messageList}
>
<ul style={{listStyle: "none"}} className="p-4 mb-0">
{updatedMessages.map((message, index) => {
return (
<li
className="mb-1"
key={index}>
<div>
{message.unique && (
<span
className="d-block font-weight-bold mt-3"
style={{color: "#000323"}}
>
<img
src={message.avatar}
style={{width: "2.5rem"}}
className="rounded-circle mr-2"
/>
{message.unique}
</span>
)}
<span
className={message.senderId === currentChatkitUser ?
"muted-blue text-light rounded d-inline-block ml-5" : "bg-secondary text-light rounded d-inline-block ml-5"
}
style={{padding:".25rem .5rem"}}
>
{message.text}
</span>
</div>
</li>
)
})}
</ul>
<TypingIndicator usersWhoAreTyping={this.props.usersWhoAreTyping}/>
<div
style={{float: "left", clear: "both"}}
ref={this.messagesEnd}>
</div>
</div>
)}
</div>
)
}
use state property(eg loading = true) at initial which wil return the rendering some loading DOM. and define a function performing all the loop activity and execute it in componentwillmount and when you finish looping set loading property of state to false by which you can make your DOM to render your list of user in render method. ( not sure if componentwillmount is deprecated ).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.