MST

星途 面试题库

面试题:React 16.x 之后生命周期变更,对 componentWillMount 有什么替代方案及原因

在 React 16.x 及之后,componentWillMount 等一些生命周期方法被标记为不安全的。请说明为什么这些方法被认为不安全,以及有哪些替代方案可以实现类似的功能,同时分析这些替代方案相比原方法的优势。
38.4万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

为什么被认为不安全

  1. 异步渲染问题:React 16 引入了异步渲染机制(Fiber)。在异步渲染过程中,组件的渲染、暂停、恢复、销毁等操作可以随时发生。componentWillMount 这类旧生命周期方法可能在组件挂载前被多次调用,因为 React 可能会在异步渲染期间尝试不同的渲染方案,而旧生命周期方法无法感知这种异步渲染的特性,可能导致数据不一致等问题。例如,在 componentWillMount 中发起网络请求,可能会因为多次调用而导致重复请求。
  2. 数据获取时机问题:旧生命周期方法没有明确区分挂载和更新阶段,在 componentWillMount 中进行数据获取等操作,无法确定数据是首次加载还是更新时获取,不利于代码的维护和理解。

替代方案

  1. 使用 constructor 进行初始化操作:在 constructor 中可以进行一些简单的状态初始化等操作。例如:
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }
  render() {
    return <div>{this.state.data}</div>;
  }
}
  1. componentDidMount 用于数据获取和副作用操作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 }));
  }
  render() {
    return <div>{this.state.data}</div>;
  }
}
  1. getDerivedStateFromProps 用于根据 props 更新 state:这是一个静态方法,会在组件挂载和更新时都被调用。可以根据 props 来更新 state。例如:
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      derivedData: props.initialValue
    };
  }
  static getDerivedStateFromProps(props, state) {
    if (props.someValue!== state.derivedData) {
      return {
        derivedData: props.someValue
      };
    }
    return null;
  }
  render() {
    return <div>{this.state.derivedData}</div>;
  }
}

替代方案的优势

  1. constructor:清晰地将初始化操作与其他生命周期逻辑分离,使得代码结构更清晰,而且不会受到异步渲染的影响,因为它在组件创建时只执行一次。
  2. componentDidMount:明确了副作用操作(如数据获取)的时机是在组件已挂载到 DOM 后,避免了在挂载前可能出现的多次调用问题,同时符合 React 的渲染流程,便于理解和维护。
  3. getDerivedStateFromProps:能够明确区分根据 props 更新 state 的逻辑,在挂载和更新时都可以使用,且是静态方法,不会访问 this,减少了潜在的错误,使代码更可预测。