一图一例理解React的getDerivedStateFromProps和componentWillReceiveProps

424 阅读1分钟

废话不说,看效果!

效果图

test1.gif

示例代码

import React, { Component } from "react";
// 测试组件;
export default class Test extends Component {
  constructor(props) {
    super(props);
    this.state = { T"test"count0iptInfo"" };
  }
  handleClick = () => {
    let { count } = this.state;
    this.setState({ count: count + 1 });
  };
  changeValue = (event) => {
    this.setState({ iptInfo: event.target.value });
  };
  render() {
    let { count, iptInfo } = this.state;
    return (
      <div>
        <p>this is Test</p>
        <p>
          {/* 测试父组件的state变化,也会触发子组件派生周期函数执行;  */}
          <input type="text" value={iptInfo} onChange={this.changeValue} />
        </p>
        <button onClick={this.handleClick}>click Btn</button>
        <Sub count={count}></Sub>
      </div>
    );
  }
}
// 子组件;
class Sub extends Component {
  state = {
    className"sub",
    count"",
  };
  //   此生命周期方法已经被替代
  //   componentWillReceiveProps(nextProps) {
  //     if (props.type !== nextProps.type) {
  //       // 在这里进行异步操作或者更新状态
  //       this.setState({
  //         type: props.type,
  //       });
  //       this._doAsyncOperation();
  //     }
  //   }
  // 生命周期: getDerivedStateFromProps
  // 主要作用是从props更新数组到state,所以需要return数据更新到state;
  // 1.静态方法;
  // 2.两个参数:一个是props,一个是state,这两个参数都是当前最新的。
  // 3.返回值: 可以返回一个对象,用于更新state, 如果判断条件不成立,也要返回,返回null即可;不返回不行;
  // 4.初始化时也触发;这是和 componentWillReceiveProps 最大的区别;
  // 5.父组件的state变化,也会触发;
  // 6.配合componentDidUpdate发起异步请求;
  // 7.此处是React中除了使用setState之外,另一个可以更新state的方式;
  static getDerivedStateFromProps(nextProps, prevState) {
    debugger;
    console.log({ nextProps, prevState });
    if (nextProps.count !== prevState.count) {
      return {
        count: nextProps.count,
      };
    }
    return null;
  }
  // 1.在componentDidUpdate中进行异步操作,驱动数据的变化
  // 2.初始化不触发;
  // 3.derived中已经执行了更新state操作,所以直接使用两次的state比较即可;
  // 4.其实在props变化,state变化都会触发这里,所以,需要加if判断,以免出现一直调用的情况;
  componentDidUpdate(prevProps, prevState) {
    let { count } = this.state;
    if (prevState.count != count) {
      console.log("异步请求!");
    }
  }
  render() {
    let { className, count } = this.state;
    return (
      <div>
        <p>this is {className}</p>
        <p>传递参数: {count}</p>
      </div>
    );
  }
}