MST

星途 面试题库

面试题:React组件从旧生命周期迁移到新生命周期的常见步骤有哪些

在React组件升级过程中,从使用旧的生命周期函数(如componentWillMount、componentWillUpdate等)迁移到新的生命周期函数(如getDerivedStateFromProps、getSnapshotBeforeUpdate等),请阐述常见的迁移步骤和需要注意的要点。
48.2万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

常见迁移步骤

  1. 分析旧生命周期使用场景
    • 梳理componentWillMount中逻辑,该函数在组件挂载到 DOM 之前调用,常用于初始化数据,比如发起一些异步请求获取初始数据。
    • 查看componentWillUpdate的使用情况,此函数在组件接收到新的 props 或者 state,即将更新之前被调用,常用于在更新前做一些准备工作,如记录旧的 props 或 state 值。
  2. 对应新生命周期替换
    • 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>;
    }
}

需要注意的要点

  1. 静态方法特性
    • getDerivedStateFromProps是静态方法,不能在其中使用this。如果需要访问实例方法或状态,应提前在构造函数或其他非静态方法中处理好。
  2. 避免无限循环
    • getDerivedStateFromProps中更新 state 时要谨慎,避免因错误判断导致反复更新,形成无限循环。确保只有在必要时才返回新的 state 对象。
  3. DOM 操作时机
    • getSnapshotBeforeUpdate用于在更新 DOM 前获取 DOM 相关信息,而componentDidUpdate用于在 DOM 更新后执行操作。要明确区分两者的使用场景,避免混淆导致逻辑错误。
  4. 异步操作位置
    • 务必将异步操作放在componentDidMount中,而不是componentWillMount,以确保组件已挂载到 DOM 上,这有助于避免一些潜在的渲染问题。