React复习(6)

React生命周期:挂载,更新,卸载,这篇文章会详细介绍各个生命周期中的钩子函数以及作用

(1)挂载阶段

class App extends React.Component {
  //1:设置默认属性
  static defaultProps = {
    n: 1,
  }
  //2:初始化状态
  //创建组件实例,本质是创建一个新的对象
  //把方法绑定到this上
  constructor(props) {
    //super本质:this.props = props,在此之后才有this实例
    console.log('constructor');
    super(props)
    this.state = {m:0}
    //绑定完this后生成一个新对象赋值给当前实例
    this.go2 = this.go2.bind(this)
  }
  //go1是对象,直接绑定到组件实例上
  go1 = {a:1}
  //go2是方法,绑定到组件原型对象上
  go2(){
    console.log(this);
  }
  //3:第一次组件渲染之前执行,只会执行一次
  //此时能够获取当前组件实例的state和props
  //该钩子函数常用在服务器端渲染
  //现已被UNSAFE_componentWillMount替代
  componentWillMount() {
    console.log('componentWillMount');
    //会报警告,推荐使用setState修改值
    this.state = {m:1}
    //可以修改值但是不会触发render,因为这时还没有render
    this.setState({m:1})
    //可以触发render,render不会阻塞渲染
    //不适合做网络请求,时机不确定,会出现二次渲染
    setTimeout(()=>{
      this.setState({m:1})
    },5000)
  }
  //4:渲染函数,纯函数
  //第一次挂载时,数据更新时会触发
  //解析jsx 虚拟DOM=>(第一次直接渲染,更新时使用diff算法)=>真实dom=>视图
  //类组件必须写该方法
  //使用setState会导致死循环,内存溢出
  render() {
    console.log('render');
    return(
      <div>
        count : {this.state.m}
        {/*绑定时先去原型对象上寻找go2,然后把这个go2绑定到组件实例上*/}
        <button onClick={this.go2.bind(this)}></button>
      </div>
    )
  }
  //5:第一次渲染完毕触发
  //网络请求,事件监听,操作dom,定时器都写在这里
  componentDidMount(){
  }
}
ReactDOM.render(<App />, document.getElementById('app'))

在声明书属性使需要注意

constructor外面的属性会按顺序陆续添加到constructor里面初始化
排在前面的属性使用到后面的属性时,后面的属性会undefined
解决方案:
1:调整顺序
2:将排在前面且需要调用后面的属性放到constructor里,
   因为初始化顺序是先初始化constructor外的属性,再初始化constructor里面的属性

(2)更新阶段

class App extends React.Component {
  constructor(props) {
    console.log('constructor');
    super(props)
    this.state = {m:0}
  }
  UNSAFE_componentWillMount(){
    console.log('UNSAFE_componentWillMount');
  }
  // 接收参数前的钩子函数
  //父组件渲染,子组件也渲染,子组件从该钩子函数开始
  //当子组件的state对props有依赖时会用到
  //使用setState不会触发render
  // componentWillReceiveProps(nextProps){
  //   console.log('componentWillReceiveProps');
  // }
  UNSAFE_componentWillReceiveProps(nextProps){
    console.log('UNSAFE_componentWillReceiveProps');
    console.log(nextProps);
    this.setState({
      m:2
    })
  }
  //1:判断是否更新
  //返回true调用render,返回false不调用
  //根据props和state判断是否重新渲染
  //状态比较:this.state和nextState(变化后的值)
  //props比较:this.props和nextProps
  shouldComponentUpdate(nextProps,nextState){
    console.log('shouldComponentUpdate');
    if(this.state.m === nextState.m && this.props.a === nextProps.a ){
      return false
    }
    return true
  }
  //2:更新前触发钩子函数
  //现已经改名为UNSAFE_componentWillUpdate
  // componentWillUpdate(){
  // }
  UNSAFE_componentWillUpdate(){
    console.log('UNSAFE_componentWillUpdate');
  }
  //3:更新渲染
  render() {
    console.log('render');
    return(
      <div>
        count:{this.state.m}
        count:{this.props.a}
        <button onClick={
          //箭头函数没有this,会找到外围的this,也就是render的this,指向组件实例
          ()=>{
            this.setState({
                m:1
              })
        }}>更新</button>
      </div>
    )
  }
  //4:更新完毕触发
  componentDidUpdate(){
    console.log('componentDidUpdate');
  }
  //5:第一次渲染完毕触发
  componentDidMount(){
    console.log('componentDidMount');
  }
}
class AppFather extends React.Component {
  constructor(props){
    console.log('father-constructor');
    super(props)
    this.state = {a:10}
  }
  UNSAFE_componentWillMount(){
    console.log('father-UNSAFE_componentWillMount');
  }
  shouldComponentUpdate(nextProps,nextState){
    console.log('father-shouldComponentUpdate');
    return true
  }
  UNSAFE_componentWillUpdate(){
    console.log('father-UNSAFE_componentWillUpdate');
  }
  render(){
    console.log('father-render');
    return(
      <div>
        {/*给子组件传值*/}
        <App a= {this.state.a} />
        <button onClick={
          ()=>{
            this.setState({
                a:12
              })
        }}>更新父类</button>  
      </div>
    )
  }
  componentDidUpdate(){
    console.log('father-componentDidUpdate');
  }
  componentDidMount(){
    console.log('father-componentDidMount');
  }
}
ReactDOM.render(<AppFather />, document.getElementById('app'))

(3)卸载阶段

class App extends React.Component {
  constructor(props) {
    console.log('constructor');
    super(props)
    this.state = {m:0}
  }
  UNSAFE_componentWillMount(){
    console.log('UNSAFE_componentWillMount');
  }
  UNSAFE_componentWillReceiveProps(nextProps){
    console.log('UNSAFE_componentWillReceiveProps');
    console.log(nextProps);
    this.setState({
      m:2
    })
  }
  shouldComponentUpdate(nextProps,nextState){
    console.log('shouldComponentUpdate');
    if(this.state.m === nextState.m && this.props.a === nextProps.a ){
      return false
    }
    return true
  }
  UNSAFE_componentWillUpdate(){
    console.log('UNSAFE_componentWillUpdate');
  }
  render() {
    console.log('render');
    return(
      <div>
        count:{this.state.m}
        count:{this.props.a}
        <button onClick={
          ()=>{
            this.setState({
                m:1
              })
        }}>更新</button>
      </div>
    )
  }
  componentDidUpdate(){
    console.log('componentDidUpdate');
  }
  componentDidMount(){
    console.log('componentDidMount');
  }
  //组件卸载钩子函数,释放资源
  //多用于隐藏显示,页面跳转,手动移除
  //想执行父组件卸载钩子,然后陆续递归执行子组件卸载钩子  
  componentWillUnmount(){
    console.log('componentWillUnmount');
  }
}
class AppFather extends React.Component {
  constructor(props){
    console.log('father-constructor');
    super(props)
    this.state = {a:10}
  }
  UNSAFE_componentWillMount(){
    console.log('father-UNSAFE_componentWillMount');
  }
  shouldComponentUpdate(nextProps,nextState){
    console.log('father-shouldComponentUpdate');
    return true
  }
  UNSAFE_componentWillUpdate(){
    console.log('father-UNSAFE_componentWillUpdate');
  }
  render(){
    console.log('father-render');
    return(
      <div>
        <App a= {this.state.a} />
        <button onClick={
          ()=>{
            this.setState({
                a:12
              })
        }}>更新父类</button>
        <button onClick={
          ()=>{
            ReactDOM.unmountComponentAtNode(document.getElementById('app'))
        }}>卸载</button>  
      </div>
    )
  }
  componentDidUpdate(){
    console.log('father-componentDidUpdate');
  }
  componentDidMount(){
    console.log('father-componentDidMount');
  }
  componentWillUnmount(){
    console.log('father-componentWillUnmount');
  }
}
ReactDOM.render(<AppFather />, document.getElementById('app'))

(4)高性能组件PureComponent

React.PureComponent和Component很相似,但是PureComponent性能更高;
它会自动检测是否需要更新
也就是自动模拟shouldComponentUpdate这个钩子函数来确保不会重复无效刷新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无非是我

不必打赏,欢迎指正

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值