React 的生命周期

1.初始化阶段

1.1 componentWillMount()

在render之前执行,在这个函数中可以进行渲染之前的最后一次 state 修改

import React, { Component } from "react";
export default class App extends Component {
  state = {
      text:"人生自古谁无死,留取丹心照汗青"
  };
  render() {
    return <div>{this.state.text}</div>;
  }
  componentWillMount(){
      this.setState({
          text:"生亦何欢,死亦何苦,喜乐悲愁,皆归尘土"
      })
  }
}

1.2 render ()

只能访问 this.props 和 this.state ,不能进行状态的修改和DOM输出

import React, { Component } from "react";
export default class App extends Component {
  state = {
    text: "人生自古谁无死,留取丹心照汗青",
  };
  render() {
    return (
      <div>
        <Child  parentText={'小楼昨夜又东风,故国不堪回首月明中'}></Child>
      </div>
    );
  }
  componentWillMount() {
    this.setState({
      text: "生亦何欢,死亦何苦,喜乐悲愁,皆归尘土",
    });
  }
}

class Child extends Component {
  state = {
      text:"春花秋月何时了,往事知多少?",
      errorText:''
  };
  render() {
  // 此处不能进行状态的修改,因为 setState 会引发 render函数的执行,如果在 render 函数里面进行 state 修改,就会引发死循环,Maximum update depth exceeded. 
  // this.setState({
    //     errorText:"雕栏玉砌应犹在,只是朱颜改"
    // })
    return <div>
    // 在这里可以访问 状态和属性
        <p>{this.state.text}</p>
        <p>{this.props.parentText}</p>
    </div>;
  }
}

1.2 componentDidMount()

执行 render() 函数之后并完成真实DOM的渲染之后触发,可以获取到DOM

import React, { Component } from "react";
export default class App extends Component {
  render() {
    return (
      <div>
          <p id="p_tag">问君能有几多愁?恰是一江春水向东流</p>      </div>
    );
  }
  componentDidMount(){
    console.log(document.getElementById('p_tag').innerText) //问君能有几多愁?恰是一江春水向东流
  }
}

1.4 componentWillReceiveProps()

父组件修改属性是触发

import React, { Component } from "react";
export default class App extends Component {
  state = {
    text: "人生自古谁无死,留取丹心照汗青",
  };
  render() {
    return (
      <div>
          <p id="p_tag" onClick={()=>{
              this.setState({
                  text:"小楼昨夜又东风,故国不堪回首月明中"
              })
          }}>问君能有几多愁?恰是一江春水向东流</p>
        <Child  parentText={this.state.text}></Child>
      </div>
    );
  }
}

class Child extends Component {
  state = {
      text:"",
  };
  render() {
    return <div>
    // 小楼昨夜又东风,故国不堪回首月明中---李煜
        <p>{this.state.text}</p>
    </div>;
  }
  componentWillReceiveProps(nextProps){
   console.log('nextProps',nextProps);
   this.setState({
       text:nextProps.parentText+"---李煜"
   })
  }
}

1.5 shouldComponentUpdate()

返回值决定是否进行render的调用,例如当点击tab切换需要进行展示数据切换,那么我们在多次点击同一个tab 时也会执行 setState() ,会执行 render 函数 ,但是我们的数据并没有变化,在数据没有改变的情况下,多次执行 render 函数,显然是不友好的,此时,我们就可以使用 shouldComponentUpdate 在做判断,是否需要执行render 函数,在shouldComponentUpdate()里面可以访问到 this.state 和 this.props ,并且接收两个形参,使我们可以访问到 nextPoprs 和 nextState ,(我觉得这个可以参考 VUE 的监听来做理解),在这个方法里面我们可以访问到 state 和 props 的新值和旧值 ,我们可以根据新值与旧值得对于来判断是否需要重新执行 render 函数

  shouldComponentUpdate(nextProps,nextState){
      return JSON.stringify(nextState)==JSON.stringify(nextState)
  }

1.6 componentWillUpdate()

组件即将更新, 在render()函数钱执行,不能进行状态和属性的更改,可以拿到 nextProps 和 nextState

1.7 componentDidUpdate()

可以进行DOM的修改

1.8 componentWillUnmount()

组件即将被卸载,可以在这个函数里面清除定时器和事件监听,如果有熟悉 VUE 的小伙伴,可以参考VUE 的 beforeDestroy 来理解

import React, { Component } from "react";
export default class App extends Component {
  state = {
      isShow:true
  };
  render() {
    return <div>
        <button onClick={()=>{
          this.setState({
              isShow:false
          })
        }}>移除</button>
        {this.state.isShow && <Child></Child>}
    </div>;
  }
}

class Child extends Component {
  render() {
    return <div>凭阑半日独无言,依旧竹声新月似当年</div>;
  }
  componentDidMount(){
    window.onresize=()=>{
        console.log(888);
    }
  }
  componentWillUnmount(){
      console.log('唉,我要被移除了');
      window.onresize=null;

  }
}

老生命周期存在的问题

componentWillMount

在 ssr 中会被多次调用,所以出触发多次,如果在这里进行事件绑定,将无法解绑,会造成内存泄漏,变得不够安全高效,逐步废弃.

componentWillReceiveProps

外部组件多次频繁的传入不同的props,会导致多次不必要的异步请求,逐步废弃

componentWillUpdate

更新前记录DOM的状态,可能会做一些处理,与componentDidUpdate 之间相隔时间如果过长,会导致状态不可信

新的生命周期

getDerivedStateFromProps

第一次初始化组件以及后续的更新过程(自身状态的更新和父组件引起的更新)会返回一个对象作为新的 state,如果返回 null 则说明不需要进行 state 的更新,在这里可以拿到 nextProps 和nextState,最新的 props 和 state, 这个方法是静态方法,静态方法的 this 指向这个类,而不是实例

import React, { Component } from "react";
export default class App extends Component {
  state = {
    name: "test",
  };
  render() {
    return (
      <div>
        <button
          onClick={() => {
            this.setState({
              name: "my love",
            });
          }}
        >
          change
        </button>
        <p>{this.state.name}</p>
        <p>{this.state.sex}</p>
      </div>
    );
  }
  //   在render之前修改 state
  //   可以对展示值做统一操作
  static getDerivedStateFromProps(nextProps, nextState) {
    console.log(nextProps, nextState);
    return {
      name: nextState.name.toUpperCase(),
    };
  }
}

getSnapshotBeforeUpdate

取代了componentWillUpdate 函数,触发时间是 update 发生的时候,在 render 之后 DOM渲染之前 返回一个值,返回的这个值 作为 componentDidUpdate 的第三个参数

import React, { Component } from "react";
import "./css/02-案例选项卡.css";
export default class App extends Component {
  state = {
    list: [
      1, 2, 34, 5, 6, 7, 78, 8, 9, 3, 4, 5, 5, 8942, 4234, 432, 43, 424, 533,
      788, 534, 423, 534,
    ],
  };
  myref=React.createRef()
  render() {
    return (
      <div className="snapshot_wrap">
        <button
          onClick={() => {
            let newList = [];
            for (let index = 0; index < 20; index++) {
              newList.push(`花明月暗笼轻雾,今宵好向郎边去.刬袜步香阶,手提金缕鞋.${index + 1}`);
            }
            this.setState({
              list: [...newList, ...this.state.list],
            });
          }}
        >
          添加邮件
        </button>
        <h1>邮箱应用</h1>
        <ul id="box" ref={this.myref}>
          {this.state.list.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      </div>
    );
  }
  getSnapshotBeforeUpdate(){
    return  this.myref.current.scrollTop
  }
  componentDidUpdate(prevProps, prevState, snapshot){
    console.log(snapshot,this.myref.current.scrollHeight);
    this.myref.current.scrollTop+=this.myref.current.scrollHeight-snapshot
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值