React之生命周期

来源:互联网 发布:软件光盘品牌 编辑:程序博客网 时间:2024/05/22 14:57

React是什么,为什么要使用它

  React是Facebook内部的一个JavaScript类库,已于2013年开源,可用于创建web用户交互界面,它引入了一种新的方式来处理浏览器DOM。
  那些需要手动更新DOM、费力记录每一个状态的日子一去不复返了——这种老旧的方式既不具备扩展性,又很难加入新的功能,就算可以,也是冒着很大的风险。
  React使用很新颖的方式解决了这些问题。
  你只需要声明式地定义各个时间点的用户界面,而无需关心在数据变化时需要更新那一部分的DOM。
  在任何时间点,React都能够以最小的DOM修改来更新整个应用程序。


1.组件的生命周期

  组件本质上是状态机,输入确定,输出一定确定。
  状态发生转换时,会触发不同的钩子函数,从而让开发者有机会做出相应。
在整个ReactJS的生命周期中,主要会经历4个阶段:创建阶段、实例化阶段、更新阶段和销毁阶段。

创建阶段

  getDefaultProps

  该阶段主要发生在创建组件类的时候,即在调用React.createClass的时候,这个阶段只会触发一个getDefaultProps方法,该方法会返回一个对象,并缓存下来,然后与父组件指定的prop对象合并,最后赋值给this.props作为该组件的默认属性。
  其中,props是一个对象,是组件用来接收外面传来的参数的,组件内部不允许修改自己的props属性,只能通过父组件来修改,getDefaultProps方法便是处理props的默认值的。

实例化阶段

    该阶段主要发生在实例化组件类的时候,也就是该组件被调用的时候,例如下面这段代码:React.render(    <List name='ReactJS'></List>,    document.getElementById('container'))

  一个实例初次被创建时所调用的生命周期方法与其他各个后续实例被创建时所调用的方法略有不同,当你首次使用一个组件类时,你会看到下面这些方法依次被调用:

  1. getDefaultProps
  2. getInitialState
  3. componentWillMount
  4. render
  5. componentDidMount

  对于该组件类的所有后续应用,你将会看到下面的方法依次被调用,注意:getDefaultProps方法已经不在列表中:

  1. getInitialState
  2. componentWillMount
  3. render
  4. componentDidMount

更新阶段(存在期)

这主要发生在用户操作之后,或者父组件有更新的时候,此时会根据用户的操作行为进行相应的页面结构的调整。
  随着应用状态的改变,以及组件逐渐受到影响,你将会看到下面的方法依次被调用:
1. componentWillReceiveProps
2. shouldComponentUpdate
3. componentWillUpdate
4. render
5. componentDidUpdate

销毁&清理期

  最后,当组件被使用完成后,componentWillUnmount方法将会被调用,目的是给这个实例提供清理自身的机会。


2.组件生命周期详解

getDefaultProps

  创建阶段,在创建组件类的时候(React.createClass)调用

  对于组件来说,这个方法只会被调用一次,实例之间共享引用(对象、数组、函数),对于那些没有被父辈指定props属性的新建实例来说,这个方法返回的对象可用于为实例设置默认的props值,处理的是属性

getInitialState

  初始化组件的state的值,其返回值会赋值给组件的this.state属性。
  对于组件的每个实例来说,这个方法的调用次数有且只有一次,在这里你将有机会初始化每个实例的state,与getDefaultProps不同的是,每次实例创建时,该方法都会被调用一次,处理的是状态
  在这个方法里,你已经可以访问到this.props

componentWillMount

  根据业务逻辑来对state进行相应的操作。
  该方法会在完成渲染之前被调用,这也是在render方法调用前,可以修改组件state的最后一次机会
  业务逻辑的处理都应该放在这里,例如对state的操作等。
  不可以在这里使用 AJax加载组件的数据,因为无法保证数据将会在组件DOM渲染完成后到达。

render

根据state的值,生成页面需要的虚拟DOM结构,并返回该结构。
  在这里你会创建渲染并返回一个虚拟DOM,用来表示组件的输出,对于每一个组件来说,render是唯一一个必须的方法,并且有特定的规则。

  render方法需要满足下面几点:
  1. 只能通过this.propsthis.state 访问数据
  2. 可以返回null、false或者任何React组件
  3. 只能出现一个顶级组件(不能返回一组元素)
  4. 必须纯净,意味着不能改变组件的状态或者修改DOM输出

  render方法返回的结果不是真正的DOM,而是一个虚拟的表现,React随后会把它和真实的DOM做对比,来判断是否有必要做出修改

componentDidMount

  使用render方法返回的虚拟DOM来创建真实的DOM结构,在render方法成功调用并且真实的DOM已经被渲染之后,你可以在componentDidMount内部通过this.getDOMNode() 方法访问到它(0.14版本之后,替换成ReactDOM.findDOMNode()

componentWillReceiveProps

  存在一个可选参数nextProps,代表从父级组件新获取到的 props,也就是相对于当前 this.props 更新的 props数据。
  当组件接收到新的props时,会触发该函数,在该函数中,可以调用this.setState方法来完成对state的修改。
  在任意时刻,组件的props都可以通过父辈组件来更改,出现这种情况时,componentWillReceiveProps方法会被调用(也就是属性被更改时调用),你可以获得更改props对象以及更新state的机会。
该方法发生在this..props被修改或父组件调用setProps()方法之后。

shouldComponentUpdate

  React非常快,不过你还可以让它更快——通过调用shouldComponentUpdate方法在组件渲染时进行金姑且优化
  如果你确定某个组件或者它的任何子组件不需要渲染新的props或者state,则该方法会返回false,返回false会阻止render的调用(以及后面几个函数都将不再调用)
  返回false是在告诉React要跳过render方法,以及位于render前后的钩子函数:componentWillUpdate&componentDidUpdate。
  简单地说,该方法用来拦截新的stateprops,然后根据事先设定好的判断逻辑,做出最后要不要更新组件的决定。
  不可以调用 setState 方法

  该方法是非必须的,并且大多数情况下没必要在开发中使用它,除非你已经确定所有的事情

componentWillUpdate

  更新完毕,和componentWillMount类似,组件会在接收到新的props或者state进行渲染之前,调用该方法(一般用来日志打印、数据获取等额外操作,一般用的不多)

  注意:你不可以在该方法中更新state或者props,而应该借助componentWillReceiveProps方法在运行时更新state

render

  根据一系列diff算法,生成需要更新的虚拟DOM结构。
  只能访问this.props和this.state,只有一个顶层组件,不允许修改状态(state)以及DOM输出(和实例阶段的render相同)

componentDidUpdate

  该方法在组件的更新已经同步到DOM中后触发。
  和componentDidMount类似,该方法给了我们更新已经渲染好的DOM机会,可以修改DOM

componentWillUnmount

  每当React使用完一个组件,这个组件就必须从DOM中卸载随后被销毁,而React是不会帮我们自动完成这件事的,所以此时,仅有的一个钩子函数就会做出相应,我们可以用它来完成所有的清理和销毁工作(比如计时器和时间监听器),这很必要。
  一般使用顶层API React.unmountComponentAtNode 来完成销毁。
  React.unmountComponentAtNode:从 DOM 中移除已经挂载的 React 组件,清除相应的事件处理器和 state。如果在 container 内没有组件挂载,这个函数将什么都不做。如果组件成功移除,则返回 true;如果没有组件被移除,则返回 false。

用法例子:
React.unmountComponentAtNode(document.getElementById('example'))
或者清理 setInterval计时器,以及与组件有关的事件:
window.removeEventListen(‘resize’, this.resizeListener)

0 0