野心勃勃的React组件生命周期

jopen 8年前

当你还在写着Angular指令,过滤器,注入,服务,提供者,视图模版的时候,是不是觉得很烦,好在这个时候,React已经神一样的出现在历史舞台。

React组件

React实现了UI=Fn(State)的思想,组件内部有自己的状态和初始的属性,组件在某一个时刻都有一个确定的状态,状态是不断变化的,变化的状态驱动着UI渲染,一切就这么简单。React让UI组件化,一个最小的组件实现,需要一个render方法即可。

 1 import React, { Component } from 'react'   2 var Dialog = React.createClass({   3     render: function(){   4         return(   5             <div>   6                 Hello React   7            </div>   8         )   9     }  10 })

组件化方便组合重用,组件有自己的生命周期,详情请阅官方文档: http://reactjs.cn/react/docs/component-specs.html

让我们来看看React组件的生命周期:

getDefaultProps: function () {      return{          //在组件类创建的时候调用一次,然后返回值被缓存下来。这是第一个触发的方法,返回的值可以用this.props访问,此值在所有实例间共享      }  }
getInitialState: function () {      return{          //在组件挂载之前调用一次。返回值将会作为 this.state 的初始值,这是第二个触发的方法      }  }
componentWillMount: function(){      //在初始化渲染执行之前立刻调用,只会调用一次      //如果在这个方法内调用 setState,render() 将会感知到更新后的 state,将会执行仅一次渲染,尽管 state 改变了。  }
componentWillReceiveProps: function (nextProps){      //该方法在初始化渲染的时候不会调用      //在组件接收到新的 props 的时候调用。      //这个方法里给你在渲染之前根据传入的属性来更新状态的机会      this.setState({title: nextProps.dialog.get('title')});  }
shouldComponentUpdate: function(nextProps, nextState) {      //该方法在初始化渲染的时候不会调用, 在使用 forceUpdate 方法的时候也不会。      //返回布尔值,true表示渲染组件,false表示本次不会运行render渲染调用,默认返回true      // 在接收到新的 props 或者 state,将要渲染之前调用。      //如果确定新的 props 和 state 不会导致组件更新,则此处应该 返回 false  }
componentWillUpdate: function (nextProps, nextState) {      //该方法在初始化渲染的时候不会调用      //在接收到新的 props 或者 state 之前立刻调用.使用该方法做一些更新之前的准备工作.      //当shouldComponentUpdate返回true时会在render之前调用.      //你不能在这个方法中使用 this.setState()。如果需要更新 state 来响应某个 prop 的改变,请使用 componentWillReceiveProps。  }
render: function () {     //初始化渲染的时候会调用,在第一次初始化渲染的时候不理会shouldComponentUpdate的返回值     //因为shouldComponentUpdate默认返回true,而第一次初始化渲染时候,shouldComponentUpdate是不会调用的,不管你返回true或false。     //有点绕,多读几遍。     //当不是初始化渲染时,如果shouldComponentUpdate返回false,则不会调用render方法。     //在这里可以使用this.props和this.state来获取数据,请不要在这个方法里改变state  }
componentDidUpdate: function (prevProps, prevState) {      //该方法在初始化渲染的时候不会调用      //组件render方法后调用此方法,在组件的更新已经同步到 DOM 中之后立刻被调用,使用该方法可以在组件更新之后操作 DOM 元素。  }
componentDidMount: function(){     //在初始化渲染执行之后立刻调用,只会调用一次     //组件已经加载到dom里,在这里可以和浏览器交互,直接操作页面上原始的Dom元素,比如$.ajax调用等等     window.addEventListener("keydown", this.listenKeyboard, true);  }
componentWillUnmount: function() {      //在组件从 DOM 中移除的时候立刻被调用。在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。      window.removeEventListener("keydown", this.listenKeyboard, true);  }

React组件页面触发结果如下:

第一次页面加载时候组件的生命周期如下:  getDefaultProps -> getInitialState -> componentWillMount -> render ->componentDidMount    如果时在Redux(后面会讲到)里加载组件,则生命周期如下:  getDefaultProps -> getInitialState -> componentWillMount -> render ->componentDidMount  -> componentWillReceiveProps -> shouldComponentUpdate    第二次生命周期:  componentWillReceiverProps -> shouldComponentUpdate -> componentWillUpdate -> render  -> componentDidUpdate    如果shouldComponentUpdate返回false,则 componentWillUpdate -> render -> componentDidUpdate这三个方法不会被触发:  componentWillReceiverProps -> shouldComponentUpdate

父子组件之间通过属性来传递数据,属性可以是普通字符串也可以是回调函数

兄弟组件之间可以给每个组件设置一个ref属性,然后同样可通过属性来传递此ref数据

但是建议不要这么做,这样结合过于紧密,正确的做法应该是通过消息来解决,

该是Flux出场的时候了,Flux是非死book推的一种解决方案,实现这种方案的框架非常之多,

该是Redux出手的时候了,它是Flux的一种实现,它让组件之间的交互,状态的维护变得简单快乐,简单快乐,简单快乐,重要的事重复说三遍。

Redux有一些基本概念

===================================

action:

事件消息对象,有一个必需的type键,对消息预处理,可以发起ajax请求数据。然后dispatch消息。

reduce:  

订阅感兴趣的消息type,对消息数据进一步的加工 ,返回的state数据即以props传入React 组件

component: 

React组件,接受Redux以props传入的actions和reduce state data,在React组件里用this.props.xxx和this.props.actions.xxx访问

====================================

组合reduce

====================================

1 import { combineReducers } from 'redux'  2 const reducers = combineReducers({  3     form,  4     items,  5     dialog  6 })

派发的消息,会挨个传入组合的reduce里,谁对消息感兴趣谁就接受此消息即可。

这样组件之间通过消息通讯,正所谓高内聚低媾合,组件之间不需要彼此知道彼此是谁,我只对数据感兴趣,那么数据怎么和组件关联上的呢,请看下面:

====================================

链接component和reduce

====================================

 1 import { bindActionCreators } from 'redux'   2 import { connect } from 'react-redux'   3 import * as AllActions from '../actions'   4 export default connect(state => ({   5     form: state.form,   6     items: state.items,   7     dialog: state.dialog,   8 }), dispatch => ({   9     actions: bindActionCreators(AllActions, dispatch)  10 }))(App)

这一步把组件和reduce返回的state链接里起来,也就是说dialog reduce返回的数据,是驱动dialog组件的UI更新,这一步比较关键,好在redux给你做了,这样让状态的管理特别简单快乐,简单快乐,简单快乐。

React和Flux(Redux)

================================

Redux里用户在页面视图上的交互会触发dom事件,dom事件会派发消息即action,消息除了必需的type之外还可以携带数据,携带的数据可以发起服务器请求获取,然后传给对这个消息感兴趣的reduce,reduce判断自己对某个消息感兴趣后,会对数据进行加工处理,最终返回一个数据对象,即state,返回的state会被Redux作为当前reduce所绑定组件的props传入React组件内部,在这个时候Redux的事件被React的事件接管进入React组件的生命周期内,React组件触发React组件的一系列事件方法,当然包括重要的render方法的调用,从而驱动了UI的更新。

在前端JS的历史舞台终于革命性的出现了一颗闪耀的新星,野心之大前所未见。

React+Flux让前端(web+mobile)阿猿们从此变的简单快乐,简单快乐,简单快乐。

</div>

来自: http://www.cnblogs.com/CHONGCHONG2008/p/5099483.html