常见迁移步骤
- 分析旧生命周期使用场景:
- 梳理
componentWillMount
中逻辑,该函数在组件挂载到 DOM 之前调用,常用于初始化数据,比如发起一些异步请求获取初始数据。
- 查看
componentWillUpdate
的使用情况,此函数在组件接收到新的 props 或者 state,即将更新之前被调用,常用于在更新前做一些准备工作,如记录旧的 props 或 state 值。
- 对应新生命周期替换:
componentWillMount
替换:
- 如果是简单的初始化状态,可以将相关逻辑移到
constructor
中。例如:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
}
- 对于异步操作,可使用`componentDidMount`。因为`componentWillMount`中发起异步请求可能导致在组件挂载前数据就已返回,而`componentDidMount`保证组件已挂载到 DOM 上,此时发起请求更合理。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
fetch('your - api - url')
.then(response => response.json())
.then(data => this.setState({ data }));
}
}
- **`componentWillUpdate`替换**:
- 如果是基于新的 props 更新 state,可使用`getDerivedStateFromProps`。该函数是一个静态方法,接收`props`和`state`作为参数,返回一个对象来更新 state,或者返回`null`表示不需要更新 state。例如:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
oldPropValue: props.value
};
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value!== prevState.oldPropValue) {
return {
oldPropValue: nextProps.value
};
}
return null;
}
}
- 若要在更新 DOM 前获取 DOM 状态,可使用`getSnapshotBeforeUpdate`。它在最近一次渲染输出(提交到 DOM 节点)之前调用,返回的任何值将作为参数传递给`componentDidUpdate`的第三个参数。例如:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevProps.value!== this.props.value) {
return this.myRef.current.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (snapshot!== null) {
this.myRef.current.scrollTop = snapshot;
}
}
render() {
return <div ref={this.myRef}>{this.props.value}</div>;
}
}
需要注意的要点
- 静态方法特性:
getDerivedStateFromProps
是静态方法,不能在其中使用this
。如果需要访问实例方法或状态,应提前在构造函数或其他非静态方法中处理好。
- 避免无限循环:
- 在
getDerivedStateFromProps
中更新 state 时要谨慎,避免因错误判断导致反复更新,形成无限循环。确保只有在必要时才返回新的 state 对象。
- DOM 操作时机:
getSnapshotBeforeUpdate
用于在更新 DOM 前获取 DOM 相关信息,而componentDidUpdate
用于在 DOM 更新后执行操作。要明确区分两者的使用场景,避免混淆导致逻辑错误。
- 异步操作位置:
- 务必将异步操作放在
componentDidMount
中,而不是componentWillMount
,以确保组件已挂载到 DOM 上,这有助于避免一些潜在的渲染问题。