繁体   English   中英

JavaScript。 反应 Redux。 异步。 渲染DOM之前循环未完成

[英]JavaScript. React. Redux. Async. Loop does not complete before rendering of DOM

我正在开发一个Messagelist组件,该组件从外部API中提取消息数据。 每条消息都包含一个UserId,我将在其中查询自己的API以获取更多用户信息。 我将foundUsers列表放在我的redux存储中,并连接了我的组件。 在渲染到DOM之前,我的目标是遍历每条单独的消息,并将userid替换为其相应用户的名称。

我遇到的问题是,在呈现组件之前,循环似乎没有完成,这给了我一些奇怪的行为。

初始渲染

半秒钟后

后循环

这是我的代码:

    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>
    )
}

最初使用状态属性(例如loading = true),它将返回渲染一些加载DOM。 并定义一个执行所有循环活动的函数,并在componentwillmount中执行它,完成循环后,将state的loading属性设置为false,可以使DOM在render方法中呈现用户列表。 (不确定componentwillmount是否已弃用)。

暂无
暂无

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

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