等待Redux道具,然后对componentDidMount中的道具进行一些操作

时间:2020-05-30 20:35:46

标签: reactjs redux react-redux

我的网站上有一个ChatBox组件,它显示用户的聊天记录。聊天记录在我的Firestore中没有排序,因此一旦我通过Redux道具(this.props.profile.chats_history)和(2)设置获取数据后,我想(1)将其在componentDidMount中从最新到最近排序聊天框状态中的“聊天列表”字段到已排序的数组。问题在于接收道具需要花费时间,并且在调用array.sort()方法时,控制台报告该数组未定义。我尝试使用async和await关键字解决此问题,但是我的解决方案无法正常工作。

我的解决方案

    async componentDidMount() {
        let chatlist;
        await this.props.profile.chats_history;
        chatlist = this.props.profile.chats_history.sort(function(a, b) {return a.time - b.time});
        this.setState({
            chatlist: chatlist
        })
    }

2 个答案:

答案 0 :(得分:1)

您可以使用chats_history而不是componentDidUpdate等待componentDidMount更新。在这里,我在this.props.chats_history上做得很深。

    const _ = require("lodash")
    componentDidUpdate(prevProps, prevState) {
          if (!_.isEqual(prevProps.profile.chats_history, this.props.profile.chats_history)) {
              chatlist = this.props.profile.chats_history.sort(function(a, b) {return a.time - b.time});
              this.setState({
                chatlist: chatlist
              })
       }
    }

基本上,这里发生的是,一旦安装了组件,this.props.chats_history就会有一些值,但是还没有真正的值列表。在某个时候,this.props.chats_history将被加载,这将触发组件更新。

每次更新componentDidUpdatethis.props时都会触发

this.state。您在我的代码中看到的自变量prevPropsprevState是对触发this.props的更新发生之前的this.statecomponentDidUpdate值的引用。

componentDidUpdate将被多次触发,并且仅当加载sort时才执行this.props.chats_history函数。为此,您将_.isEqualprevProps.chats_history(与this.props.chats_history进行比较。它们是否不相等相等,这意味着this.props.chats_history刚刚被修改(在本例中为已加载),因此仅在这种情况下才调用sort

我从_.isEqual库中使用lodash的原因是,如果我进行了=====比较,它将总是返回true,因为{ {1}}是一个数组,因此它将比较引用而不是数组的内容。如果您使用this.props.chats_history,则会进行深度比较,并且仅在_.isEqual的每个元素等于true的每个元素时才返回this.props.chats_history

由于您随后调用prevProps.chats_history,因此将再次调用this.setState(),但是componentDidUpdate块将返回if,并且不会再次运行false代码。

这有意义吗?

答案 1 :(得分:0)

您可以改用getDerivedStateFromProps。

static getDerivedStateFromProps(props, state) {
    const sortedChat = props.profile.chats_history?[...props.profile.chats_history].sort((a,b)=>{/*logic*/}):[]
    return { sortedChat };
}

您可以通过比较状态中的当前数据和道具中的接收数据来优化渲染。这再次取决于您的数据。就个人而言,我将在profile.chats中保留一个时间戳,并仅在时间戳更改时更新状态。此外,排序会更改原始数组的顺序。因此,请在进行上述操作之前先进行克隆。