angular1与react生命周期对比

可否理解一个组件的生命周期是很是重要的,甚至能够说是最重要的内容,他是一切进阶的基石,下面咱们就从angular1的生命周期开始吧。html

angular1生命周期

angular1的生命周期在1.5以前是很晦涩的,controller、compile、preLink、postLink,compile的return函数。从字面上让人彻底摸不着头脑,到了1.5增长了angular.component,这一问题有了很大改观,生命周期所有放到controller(controller再也不做为一个生命周期钩子存在),controller就是一个class,实例函数$onInit、$onPostLink和$onDestroy组成了新的生命周期钩子,从字面上也容易理解了不少。$onInit表明编译前,在这里你能够对$scope作属性变动,和逻辑定义;$onPostLink表明编译后,这个时候子指令已完成了编译,你能够在这里获取到任意子指令实例并调用其方法;$onDestroy在当前scope被销毁时调用,在这里你须要对dom作销毁,以及可能的全局变量作清空。很简单就是组件编译前、组件编译后和组件销毁时。那么咱们再看看react的生命周期钩子。react

react生命周期

react的生命周期分为三大阶段,git

  • 插入dom(mount)
  • 从新render(update)
  • 销毁dom(unmount)

在定义class(组件)的时候其实就是在定义一个状态机,定义了各类状态的响应,这里包括这三大阶段的钩子以及事件响应,等待触发条件的知足。github

1 插入dom(mount)算法

先来讲下第一阶段,首次render触发时会执行如下钩子函数,redux

  • getDefaultProps
    getDefaultProps: function(){
      return { /* 默认属性 */};
    }复制代码
  • getInitialState性能优化

    getInitialState: function(){
      return { /* 初始状态 */};
    }复制代码

    这两个函数不难理解,目的是使代码结构更清晰,不须要在constructor里作过多的打底处理。dom

  • componentWillMount
    这个方法在出现class XX extends React.Component以后其实就能够用constructor来代替了。对于angular1.5这和$onInit也是相似的,一样也能够用constructor代替。异步

  • render
    这个函数其实和angular指令中的template属性(值对应一个函数)很类似,可是借助jsx,render比template属性强大实在太多,angular所提供的template不够灵活,在template函数中没法拿到$scope,天然咱们就选择例如ngIf这样的属性指令来作模版输出控制,该指令会在当前指令做用域下再建立一个子做用域,这使得咱们在获取子组件的实例的时候会比较麻烦,ngRepeatngSwitch都是这样,angular1的初衷是不但愿咱们本身作字符串拼接,的确就算咱们能拿到$scope,字符串拼接也实在不够优雅。
    因此render函数直白点完成了两件事情:函数

    • 执行jsx表达式,生成最终插入dom容器节点的真实dom(这里不考虑虚拟dom的问题)
    • 借助react提供的synthetic event system完成事件监听绑定

    全部叶子组件的jsx模版都是由基础原生html标签、属性以及react所提供的代理属性组成的,所以若是你写以下一段模版代码:

    render(){
      return (
          <div num=1 changehandler={this.changeHandler.bind(this)}/> ) }复制代码

    numchangehandler属性会直接被忽略,若是你想在原生标签上使用自定义属性,请在属性前面添加data-

  • componentDidMount

    componentDidMount和angular中的link或postLink很类似,可是它更让人放心,由于angular中若是你想在link中获取带有ngIf或ngRepeat的dom是获取不到的(由于会再transclude一次并等待下次脏数据校验才会插入dom,有兴趣的同窗能够移步重复transcludengIf脏数据校验),所以在这里你能够放心的访问dom。

    小结:上述方法除了render,只会伴随第一次render执行一次。

2 从新render

当组件props和state(经过setState)发生变动时,会触发re-render操做。所以这里咱们把state和props变化分开来讲。

在angular1中其实并无屡次触发的钩子,像前面说到的controller、compile等也都只执行一次,其实react的从新渲染在angular相似$watch,通常咱们在$watch来实现dom的变动,这种命令式的修改dom固然是不推荐的,react采用了一种更完全的方式,给人的感觉就像又走了一遍第一次渲染同样,而你能够这样理解,相对于第一次,它可能仅仅变动了个别state或props,经过虚拟dom和diff算法,react帮助你高效的将变动应用于虚拟dom上最终re-render出新的dom树。

2.1 state变动

状态变动会触发如下几个钩子

  • shoudComponentUpdate
    shouldComponentUpdate: function(nextProps, nextState){
          return true
      }复制代码
    该函数给用户一个机会使得其能够控制是否须要进行从新渲染,angular1并无提供终止指令编译的钩子函数,这是react的高级特性了,主要针对性能优化,本身没有用过就不误导你们了。
  • componentWillUpdate

    componentWillUpdate: function(nextProps, nextState){
      // 为re-render作准备
      }复制代码

    为啥须要这个钩子呢,由于只有shouldComponentUpdate返回true才能肯定必定会从新渲染,那么在这里咱们能够对界面的提示UI作变动,好比以前为了获取state或props会由于异步请求出现loading,那么这个时候就能够隐藏loading。记住这里不能有任何会再次触发组件从新渲染的逻辑。

  • componentDidUpdate

    componentDidUpdate: function(prevProps, prevState){
      // 能够访问渲染完成的dom
    }复制代码

    这个没啥可说的,和componentDidMount是同样的。

2.2 props变动

componentWillReceiveProps: function(nextProps) {
  this.setState({
    // new state
  });
}复制代码

不像state须要调用setState才会触发re-render,由父组件致使的任何属性变动都会触发re-render,不须要调用额外的方法。其实props变动所经历的生命周期钩子和state几乎同样,惟一不一样是在shouldComponentUpdate以前增长了componentWillReceiveProps,用意也十分明显,咱们能够在componentWillReceiveProps中经过setState对state作修改,好比组件内部的state是根据某个或多个props计算得出的,这样咱们在调用setState时候也不会形成额外的re-render被触发,深刻理解react

3 销毁dom(unmount)
当咱们改变UI布局或者使用接口删除组件树上某个组件时就会触发组件的componentWillUnmount方法,在这里你能够取消事件监听或定时器,以及其余会形成全局引用的变量。

class App extend Component {
    componentWillUnmount(){
        // unregister event or clear timer
    }
}
render(<App />, document.getElementById('root') function ummount(){ React.unmountComponentAtNode(document.getElementById('root')); }复制代码

4 结束
这篇其实和angular1的对比不是太多,但其实大概的生命周期和angular1仍是大同小异,特别是re-render这块更有条理也更有性能优点。react与angular1的对比先暂告一段落,后面将开始redux的学习,同时会对官方的demo作详细讲解。

文中若有错误请你们及时纠正,谢谢。

相关文章
相关标签/搜索