React的生命周期

161 阅读3分钟

React的生命周期分为好几个阶段,我将记录几个重要的生命周期钩子

  • constructor()-在这里初始化state

  • shouldComponentUpdate()-return false阻上更新

  • render()-创建虚拟DOM

  • componentDidMount()-组件已出现在页面

  • componentDidUpdate()-组件已更新

  • componentWillUnmount()-组件将死

constructor初始化

初始化props,state,方法,此时不调用setState,

shouldComponentUpdate

用途:

  • 返回true表示不阻止UI更新
  • 返回false表示阻止UI更新 VUE从来不用控制UI更新,因为vue监听了数据,一改变就会自动更新

案例:点击+1操作我+1之后立即又-1,此时UI上没变,n还是0,按理来说不会执行render(),但是render函数执行了

  add=()=>{
    this.setState(
      (state)=>({
        n: state.n+1
      })
    )
    this.setState(
      (state)=>({
        n: state.n-1
      })
    )
  };

render(){
    console.log('render了1次')
    return(
      <div>
        n:{this.state.n}
        <button onClick={this.add}>+1</button>
      </div>
    )
  }
};

由于n是新对象和老n的地址不一样,导致react认为数据变了,就会重新render,此时就可以用shouldComponentUpdate阻止更新UI 第一个参数是新生成的props,第二个参数是新的state数据,当老的n和新的n数据一样时就返回false,就会阻止UI跟新不会执行render

add=()=>{
    this.setState(
      (state)=>({
        n: state.n+1
      })
    )
    this.setState(
      (state)=>({
        n: state.n-1
      })
    )
  };
  
  shouldComponentUpdate(newProps,newState){
    if(newState.n === this.state.n){
      return false
    }else{
      return true
    }
  };
  render(){
    console.log('render了1次')
    return(
      <div>
        n:{this.state.n}
        <button onClick={this.add}>+1</button>
      </div>
    )
  }
};

如果有很多个这样的变量我们难道要一个个比较吗?React做了一个方法 原先我们定义一个组件使用时

class App extends React.Component{}

React的新方法是, PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。 如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。

class App extends React.PureComponent{}

问:shouldComponentUpdate有什么用?

答:它允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要的更新

render渲染

用途

  • 展示视图
  • return(<div>...</div>)//(...)这是一个虚拟DOM
  • 只能有一个根元素
  • 如果有两个根元素,就要用<React.Fragment>包起
  • <React.Fragment/>可以缩写成<> </> 技巧
  • render里面可以写if..else
  • render里面可以写?:表达式
  • render里面不能直接写for循环,需要用数组
  • render里面可以写array.map(循环)

componentDidMount()组件已经挂载了

用途

  • 在元素插入页面后执行代码,这些f码依赖DOM
  • 比如你想获取 div的高度,就最好在这里写
  • 此处可以发起加载数据的AJAX请求(官方推荐)
  • 首次渲染会执行此钩子

componentDidUpdate

用途

  • 在视图更新后执行代码
  • 此处也可以发起AJAX请求,用于更新数据(看文档)
  • 首次渲染不会执行此钩子
  • 在此处setState可能会引起无限循环,除非放在if里
  • 若shouldComponentUpdate 返回false,则不触发此钩子

componentWillUnmount

消除一些做出的动作

用途

  • 组件将要被移出页面然后被销毁时执行代码
  • unmount过的组件不会再次mount 举例
  • 如果你在componentDidMount里面监听了window scroll
  • 那么你就要在componentWillUnmount里面取消监听
  • 如果你在componentDidMount里面创建了Timer
  • 那么你就要在componentWillUnmount里面取消Timer
  • 如果你在componentDidMount里面创建了AJAX请求
  • 那么你就要在componentWillUnmount里面取消请求
  • 原则:谁污染谁治理