React生命周期。

594

〇、对于一个普通的div创建过程,有着如下的步骤:

  1. const div=document.createElement("div"):div的create/construct
  2. div.textContent="hi":初始化state(数据)
  3. document.body.appendChild(div):div mount 在body上
  4. div.textContent="hi2":update 全新的state
  5. div.remove():将div unmount

一、React中的生命周期

  1. constructor()
  2. static getDerivedStateFromProps()
  3. shouldComponentUpdate()
  4. render()
  5. getSnapshotBeforeUpdate()
  6. componentDidMount()
  7. componentDidUpdate()
  8. componentWillUnmount()
  9. static getDerivedStateFromError()
  10. componentDidCatch()

二、shouldComponentUpdate()

用途:

  1. 返回true表示不阻止页面更新
  2. false表示阻止页面更新

一个栗子:
对于一个组件,假如state通过一系列变化,最后数值没有变,但是由于state对象是变化的,必然导致强行更新UI,这是不利于用户体验的。于是就有了这个钩子,询问你是否更新:

image.png 即使点击了button,n+1-1生成的n没变,但是依然会生成{n:1}新对象。这个新对象会调用render()函数触发更新。

image.png

于是可以使用shouldComponentUpdate()去判断是否需要更新

image.png shouldComponentUpdate里面有两个参数,一个是nextProps(新的props)和nextState(新的state),通过对比新的state里的数据和旧的state的数据是否相同判断要不要render()

image.png

另外,其实对比新的state和旧的state的数据是否变没变有利于优化react的渲染体验,去掉不必要的渲染,React难道没想过这个吗?需要我们手动判断是否需要渲染吗

这个功能其实已经内置了,叫React.PureComponent

image.png 使用PureComponent,点击按钮,“UI渲染”字段不会再出现。


三、render()

顾名思义,用来渲染视图。
但是有一点,return的东西只能有一个根元素 例如:

return (
    <div>
        <div className="innnercontent1">这是里面1</div>
        <div className="innnercontent2">这是里面2</div>
    </div>
)   

假如把最外面的div去掉,会报错:

    //这样return是必报错的,因为没有一个根元素包裹
    return (
         <div className="innnercontent1">这是里面1</div>
         <div className="innnercontent2">这是里面2</div>
    )

解决方法:使用React.Fragment

return (
   <React.Fragment>
       <div className="innnercontent1">这是里面1</div>
       <div className="innnercontent2">这是里面2</div>
   </React.Fragment>
   
   //或者直接<></>
    <>
       <div className="innnercontent1">这是里面1</div>
       <div className="innnercontent2">这是里面2</div>
   </>
)  

四、componentDidMount()

  1. 组件挂载到页面上后立刻执行代码 ,很明显这些代码是需要依赖dom的
  2. 这个地方也可以发起加载AJAX请求来加载数据(一般用于服务端渲染)

栗子:你想获取组件中div的宽度,肯定是在挂载后再获取的:

image.png

注意析构写法,栗子let obj={a:1,b:2,c:3} let {a,c}=obj

此外,我们还可以使用ref来定位div。 image.png

  1. 在构造器中创建一个refthis.myRef=React.createRef()
  2. 挂载后,使用this.myRef.current引用这个div,进行处理
  3. 在标签中写ref属性,用创建的myRef赋给ref

四、componentDidUpdate()

  1. 在视图更新后执行代码
  2. 此处也可以发起AJAX请求,用于数据更新(文档)
  3. 首次渲染不会触发更新,所以不会触发此钩子
  4. 此处最好不要直接使用setState,因为设置了数据后就会触发UI更新,UIgengxin后又会触发此钩子,会无限循环。可使用if等语句作判断。
  5. 如果shouldComponentUpdate设置为false,则不会触发更新

五、componentWillUnmount()

  1. 组件将要被移出页面然后销毁时执行的代码
  2. unmount后的组件不会再被mount

解决的问题:
如果在componentDidMount里面监听了window scroll 或者 Timer 或者AJAX请求
最后需要在componentWillUnmount()里取消这些操作,为了释放用户的内存