等待 Redux props,然后在 componentDidMount 中的 props 上做一些操作



我的网站有一个ChatBox组件,它显示用户的聊天记录。聊天记录在我的 firestore 中没有排序,所以我想 (1( 在通过 Redux props (this.props.profile.chats_history( 获取数据后,在 componentDidMount 中从最晚到最不新鲜进行排序,并且 (2( 将字段"chatlist"设置为排序数组的状态。问题是接收 props 需要时间,当调用 array.sort(( 方法时,控制台报告数组未定义。我试图通过使用异步和等待关键字来绕过它,但我的解决方案不起作用。

我的解决方案

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

您可以做的是等待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,这将触发组件更新。

每次更新this.propsthis.state时都会触发componentDidUpdate。您在代码中看到的参数prevPropsprevState是对触发componentDidUpdate的更新发生之前this.propsthis.state值的引用。

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

我使用lodash库中_.isEqual的原因是,如果我进行=====比较,它将始终返回truethis.props.chats_history因为它是一个数组,因此它将比较引用而不是数组的内容。如果使用_.isEqual它会进行深入比较,并且仅当this.props.chats_history的每个元素都等于prevProps.chats_history的每个元素时才返回true

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

这有意义吗?

你可以改用getDerivedStateFromProps。

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

您可以通过比较状态中的当前数据和 props 中接收的数据来优化渲染。这再次取决于您的数据。就个人而言,我会在profile.chats中保留时间戳,并且仅在时间戳更改时才更新状态。此外,排序会更改原始数组顺序。所以,在你像我上面所做的那样排序之前克隆。

最新更新