如何使用异步更新编写 shouldComponentUpdate
How to write shouldComponentUpdate with async update
我的 React class EventTable 有几种模式,根据模式,它从服务器获取不同的数据并将它们显示到 <Table>
。我首先让 class 显示静态数据,它工作得很好,包括通过来自更高组件的 prop 切换模组。但是后来我从 fetch 切换到动态数据(ApiHelper
中的函数 updateData()
),现在我遇到了问题。
我想不出正确的 shouldComponentUpdate
函数。在当前状态下,class 在获取完成之前呈现,因此在初始模式下,它不显示任何内容,当模式更改时,它显示上次获取的数据。
例如,我尝试将旧数据与 shouldComponentUpdate
中的新数据进行比较,或者仅在 eventsLoaded
为真时更新并在获取之前将其设为假,但随后它打破了方式,即组件无限更新,这有时会导致在更改模式和服务器流量垃圾邮件时出现闪烁。
class EventTable extends React.Component {
constructor(props)
{
super(props);
this.state = {
eventsLoaded: false,
data: undefined
};
}
componentDidMount() {
this.updateData();
}
componentDidUpdate() {
this.updateData();
}
shouldComponentUpdate(nextProps, nextStates) {
return this.props.mode !== nextProps.mode;
}
updateData() {
if(this.props.mode === 0)
ApiHelper.getAllEvents().then((result) => this.setState({data: result, eventsLoaded: true}));
else if(this.props.mode === 1)
ApiHelper.getMemberEvents(this.props.userToken).then((result) => this.setState({data: result, eventsLoaded: true}));
else
ApiHelper.getPastEvents().then((result) => this.setState({data: result, eventsLoaded: true}));
}
render() {
//rendering a <Table> using this.state.data
}
}
shouldComponentUpdate
在这里没有给你任何好处;它只是让事情变得更难(防止组件在您设置状态时重新呈现,这正是您想要的)。我现在会把它拿出来,只有当您将 React 性能确定为一个问题,尤其是这个组件是一个原因时,才担心实施它。
然后,您想将上一个道具与下一个道具检查(目前在 shouldComponentDidUpdate
中)添加到 componentDidUpdate
,并且仅在道具发生变化时调用 this.updateData
。如果您不将其包装在条件中,它将在每次渲染后触发,这可能导致循环行为。
有了这些更改,初始渲染和对 mode
道具的更改都将触发对 updateData
的调用,这将发出请求和更新状态,这将触发使成为。渲染之后,componentDidUpdate
将触发,但看到道具没有改变,所以它不会尝试重新获取。
我的 React class EventTable 有几种模式,根据模式,它从服务器获取不同的数据并将它们显示到 <Table>
。我首先让 class 显示静态数据,它工作得很好,包括通过来自更高组件的 prop 切换模组。但是后来我从 fetch 切换到动态数据(ApiHelper
中的函数 updateData()
),现在我遇到了问题。
我想不出正确的 shouldComponentUpdate
函数。在当前状态下,class 在获取完成之前呈现,因此在初始模式下,它不显示任何内容,当模式更改时,它显示上次获取的数据。
例如,我尝试将旧数据与 shouldComponentUpdate
中的新数据进行比较,或者仅在 eventsLoaded
为真时更新并在获取之前将其设为假,但随后它打破了方式,即组件无限更新,这有时会导致在更改模式和服务器流量垃圾邮件时出现闪烁。
class EventTable extends React.Component {
constructor(props)
{
super(props);
this.state = {
eventsLoaded: false,
data: undefined
};
}
componentDidMount() {
this.updateData();
}
componentDidUpdate() {
this.updateData();
}
shouldComponentUpdate(nextProps, nextStates) {
return this.props.mode !== nextProps.mode;
}
updateData() {
if(this.props.mode === 0)
ApiHelper.getAllEvents().then((result) => this.setState({data: result, eventsLoaded: true}));
else if(this.props.mode === 1)
ApiHelper.getMemberEvents(this.props.userToken).then((result) => this.setState({data: result, eventsLoaded: true}));
else
ApiHelper.getPastEvents().then((result) => this.setState({data: result, eventsLoaded: true}));
}
render() {
//rendering a <Table> using this.state.data
}
}
shouldComponentUpdate
在这里没有给你任何好处;它只是让事情变得更难(防止组件在您设置状态时重新呈现,这正是您想要的)。我现在会把它拿出来,只有当您将 React 性能确定为一个问题,尤其是这个组件是一个原因时,才担心实施它。
然后,您想将上一个道具与下一个道具检查(目前在 shouldComponentDidUpdate
中)添加到 componentDidUpdate
,并且仅在道具发生变化时调用 this.updateData
。如果您不将其包装在条件中,它将在每次渲染后触发,这可能导致循环行为。
有了这些更改,初始渲染和对 mode
道具的更改都将触发对 updateData
的调用,这将发出请求和更新状态,这将触发使成为。渲染之后,componentDidUpdate
将触发,但看到道具没有改变,所以它不会尝试重新获取。