美文网首页
一个小例子带你搞懂React的生命周期

一个小例子带你搞懂React的生命周期

作者: 我没叫阿 | 来源:发表于2020-01-10 12:31 被阅读0次
import React from 'react';
import ReactDOM from 'react-dom';

export default class Demo extends React.Component {
  constructor() {
    super();
    console.log('constructor-构造器');
    this.state = {
      count: 0,
      carName: '奔驰',
      newsArr: [],
    };
  }

  static getDerivedStateFromProps(props, state) {
    // 从props得到一个派生的状态,官方原话:此方法适用于罕见的用力,即state的值在任何时候都取决于props。
    console.log('getDerivedStateFromProps-', props, state);
    return null;
    // return props
  }
  /*
    getSnapshotBeforeUpdate() 在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息(例如,滚动位置)。此生命周期方法的任何返回值将作为参数传递给 componentDidUpdate()
  */
  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 更新前获取快照
    console.log('getSnapshotBeforeUpdate-', prevProps, prevState);
    return this.refs.list.scrollHeight
  }
  /* 生命周期可以分为三个部分  */
  // 1.初始化阶段
  // componentWillMount() {
  //   console.log('componentWillMount-组件将要挂载');
  // }

  componentDidMount() {
    // 此时组件已经挂载,可以进行dom操作
    // 在这个钩子中做初始化的事,例如:发送网络请求、开启定时器等
    console.log('componentDidMount-组件挂在完毕');

    // 模拟网络请求
    setInterval(() => {
      const { newsArr } = this.state;
      const news = '新闻' + (newsArr.length + 1);
      this.setState({
        newsArr: [news, ...newsArr],
      });
    }, 2000);
  }
  // 2.更新阶段
  shouldComponentUpdate() {
    //返回true或者false,true则组件更新,false不更新
    console.log('shouldComponentUpdate-组件是否更新,返回布尔值');
    return true;
  }
  // componentWillUpdate() {
  //   // 利用 this.forceUpdate() 做强制更新,不受shouldComponentUpdate()的控制
  //   console.log('componentWillUpdate-组件将要更新');
  // }
  componentDidUpdate(prePropx, preState, SnapshotValue) {
    // 接收两个参数,1:更新前传递的props,2:更新前的状态,3:getSnapshotBeforeUpdate返回的值
    console.log('componentDidUpdate-组件已经更新', prePropx, preState, SnapshotValue);
    this.refs.list.scrollTop  += this.refs.list.scrollHeight - SnapshotValue
  }
  // 3.卸载阶段
  componentWillUnmount() {
    // 组件的卸载前执行的逻辑
    // 在这个钩子中做收尾的事,例如:关闭定时器等
    console.log('componentWillUnmount-组件将要卸载');
  }

  /* 
    新的生命周期 
    getDerivedStateFromProps() {}
    getSnapshotBeforeUpdate(){}

    新版本中的生命周期不推荐使用(react文档里的原话:下述方法即将过时,在新代码中应该避免使用它们),
    componentWillMount(){}、componentWillUpdate(){}、componentWillReceiveProps(){},但是仍然可以使用,控制台会提示弃用警告。
    改成UNSAFE_componentWillMount(){}、UNSAFE_componentWillUpdate(){}、UNSAFE_componentWillReceiveProps(){}警告消失
  */
  /*
    react新旧生命周期对比
    旧的生命周期即将废弃  componentWillMount(){}、componentWillUpdate(){}、componentWillReceiveProps(){},

    新的生命周期增加了 getDerivedStateFromProps() {}、getSnapshotBeforeUpdate(){}
  */
  add() {
    this.setState({
      count: this.state.count + 1,
    });
  }
  force() {
    this.forceUpdate();
  }
  changeCar() {
    this.setState({
      carName: 'BMW',
    });
  }

  render() {
    console.log('render-组件渲染');
    return (
      <div>
        <h2>当前求和为 {this.state.count}</h2>
        <button onClick={this.add.bind(this)}>+1</button>
        <button onClick={this.force.bind(this)}>强制更新</button>
        <button onClick={this.changeCar.bind(this)}>换车</button>
        <hr />
        <p>使用getSnapshotBeforeUpdate的例子</p>
        <div style={{ width: '200px', height: '150px', background: '#ccc', overflow: 'auto',margin:'0 auto' }} ref="list">
          {this.state.newsArr.map((item, index) => {
            return (
              <div style={{ height: '30px' }} key={index}>
                {item}
              </div>
            );
          })}
        </div>
        <hr />
        {/* <Child carName={this.state.carName} /> */}
      </div>
    );
  }
}
class Child extends React.Component {
  componentDidMount() {
    console.log('子组件-componentDidMount-组件挂在完毕');
  }
  componentWillReceiveProps(props) {
    console.log('子组件-componentWillReceiveProps-父组件传递的属性有变化,做出相应', props);
  }
  render() {
    return (
      <div>
        <p>我是子组件,我拿到的车是{this.props.carName}</p>
      </div>
    );
  }
}

相关文章

网友评论

      本文标题:一个小例子带你搞懂React的生命周期

      本文链接:https://www.haomeiwen.com/subject/uimpactx.html