新生命周期函数getDerivedStateFromProps
react 16.3后更新了生命周期函数,不建议使用原来的componentWillReceiveProps、componentWillUpdate、componentWillMount,增加了getDerivedStateFromProps函数。
新的生命周期函数 getDerivedStateFromProps 位于 Mounting 挂载阶段和由 props 更新触发的 Updating 阶段。getDerivedStateFromProps 主要用于替换 componentWillReceiveProps 函数,即根据 props 更新组件的 state。两个参数也很好理解:传入的props和之前的state
class Example extends React.Component {
getSnapshotBeforeUpdate(nextProps, prevState) {
// ...
}
}
实现目标
代码基于antd Version 2.0实现,假设有2个组件,父组件和子组件,我们现在需要实现如下功能:
- 父组件根据Select框选择子组件的设备代码
- 子组件中设置定时器,定时刷新某设备的实时数据,并显示在Table中
- 父组件通过props传递设备代码给子组件,如果父组件传入的设备代码和子组件state中的设备代码不符,则更新子组件的设备代码,子组件刷新新设备的实时数据并显示在Table中
相关代码
父组件
父组件传递属性dev给子组件
<MeasurementTable
currentDevice={
dev} // dev表示传递给子组件MeasurementTable的props
loading={
loading}
/>
子组件
componentDidMount中设置定时器
componentDidMount() {
this.getRealtimeMeasurement(); // 第一次初始化的时候获取一次设备的实时数据
// getRealtimeMeasurement获取设备的实时数据,时间间隔5s
this.timer = setInterval(() => {
this.getRealtimeMeasurement();
}, 5000);
}
静态方法getDerivedStateFromProps判断传入的设备代码和现在的设备代码是否相符,相符的话就继续启动定时器获取原有设备的实时数据,否则把新设备的代码放入子组件的state中。
static getDerivedStateFromProps(nextProps, prevState) {
const {
currentDevice } = nextProps; // 父组件传入的设备代码
const {
device } = prevState; // 子组件state中存储的设备代码
if (currentDevice !== device) {
// 父组件传入的设备代码不符的时候,更新子组件的设备代码
return {
device: currentDevice,
};
}
return null;
}
自定义方法getRealtimeMeasurement根据设备代码获取设备的实时数据
getRealtimeMeasurement = () => {
const {
device } = this.state; // 从子组件的state中获取设备代码
// 根据设备代码获取设备的实时数据并存储在state中用于子组件Table更新
getMeasurementValuesByDevice(device).then(response => {
if (Object.keys(response).length !== 0) {
this.setState({
dataSource: response.data,
});
}
});
};
componentWillUnmout中清空定时器
// 清理无效timer,setState无效
componentWillUnmount() {
const {
timer } = this.state;
if (timer != null) {
clearInterval(timer);
}
}
总结
不要在getDerivedStateFromProps中设置定时器,
否则页面一直在获取,进入不到render。