MST

星途 面试题库

面试题:React 的 getDerivedStateFromProps 与 componentWillReceiveProps 的差异及应用场景

在 React 生命周期中,`getDerivedStateFromProps` 取代了 `componentWillReceiveProps`。请详细阐述两者的主要差异,以及在哪些情况下更适合使用 `getDerivedStateFromProps` 而不是 `componentWillReceiveProps`,并结合实际代码示例进行说明。
26.8万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

主要差异

  1. 调用时机与参数
    • componentWillReceiveProps:在组件接收到新的 props 时被调用,其参数为新的 props。它在 render 之前调用,并且在初始化渲染时不会被调用。例如:
    import React, { Component } from'react';
    class MyComponent extends Component {
      componentWillReceiveProps(nextProps) {
        console.log('componentWillReceiveProps called with new props:', nextProps);
      }
      render() {
        return <div>My Component</div>;
      }
    }
    
    • getDerivedStateFromProps:也是在组件接收到新的 props 时被调用,它是一个静态方法,第一个参数为新的 props,第二个参数为当前的 state。并且在初始化渲染和后续 props 更新时都会被调用。例如:
    import React, { Component } from'react';
    class MyComponent extends Component {
      static getDerivedStateFromProps(nextProps, prevState) {
        console.log('getDerivedStateFromProps called with new props:', nextProps, 'and prevState:', prevState);
        return null;
      }
      render() {
        return <div>My Component</div>;
      }
    }
    
  2. 副作用处理
    • componentWillReceiveProps:可以在这个方法中执行副作用操作,例如发起网络请求等。但是从 React v16.3 开始,它被标记为不安全的生命周期方法,因为在异步渲染模式下,它可能会在 render 之后被调用多次,导致不一致的状态更新。
    • getDerivedStateFromProps:由于是静态方法,不能直接访问 this,也就不能执行副作用操作。它的主要目的是根据 props 的变化来更新 state,应该是一个纯函数,返回一个对象来更新 state 或者 null 表示不需要更新 state
  3. 状态更新逻辑
    • componentWillReceiveProps:在该方法中,可以直接通过 this.setState 来更新状态,例如:
    import React, { Component } from'react';
    class MyComponent extends Component {
      componentWillReceiveProps(nextProps) {
        if (nextProps.someValue!== this.props.someValue) {
          this.setState({ someState: nextProps.someValue });
        }
      }
      render() {
        return <div>My Component</div>;
      }
    }
    
    • getDerivedStateFromProps:需要通过返回一个对象来更新状态,例如:
    import React, { Component } from'react';
    class MyComponent extends Component {
      static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.someValue!== prevState.someValue) {
          return { someState: nextProps.someValue };
        }
        return null;
      }
      render() {
        return <div>My Component</div>;
      }
    }
    

适用场景

  1. 适合 getDerivedStateFromProps 的场景
    • 简单的 props 驱动的状态更新:当 state 完全依赖于 props 并且更新逻辑简单时,使用 getDerivedStateFromProps 更合适。例如,一个显示用户信息的组件,当 props 中的用户数据变化时,state 也需要相应更新。
    import React, { Component } from'react';
    class UserInfo extends Component {
      state = {
        name: ''
      };
      static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.user && nextProps.user.name!== prevState.name) {
          return { name: nextProps.user.name };
        }
        return null;
      }
      render() {
        return <div>{this.state.name}</div>;
      }
    }
    
    • 避免副作用:如果不需要在 props 更新时执行副作用操作,只是单纯根据 props 更新 stategetDerivedStateFromProps 是更好的选择,因为它可以确保在异步渲染模式下的稳定性。

而当需要在 props 更新时执行副作用操作(如网络请求),或者状态更新逻辑比较复杂且需要访问 this 上下文时,getDerivedStateFromProps 就不太适用,可能需要结合 componentDidUpdate 等其他生命周期方法来替代 componentWillReceiveProps 的功能。