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

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

 import React, { Component } from 'react'
 var Dialog = React.createClass({
     render: function(){
         return(
             <div>
                 Hello React
            </div>
         )
     }
 })

组件化方便组合重用,组件有自己的生命周期,详情请阅官方文档: 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是facebook推的一种解决方案,实现这种方案的框架非常之多,
该是Redux出手的时候了,它是Flux的一种实现,它让组件之间的交互,状态的维护变得简单快乐,简单快乐,简单快乐,重要的事重复说三遍。

Redux有一些基本概念
===================================
action:
    事件消息对象,有一个必需的type键,对消息预处理,可以发起ajax请求数据。然后dispatch消息。

 export function dialogAction(data, e) {
     return {
         type: ActionTypes.DIALOG,
         data: data
     }
 }

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

 const initialItem = Immutable.fromJS({
     title: "",
     item: {},
     isVisible: false,
     ok: null,
     cancel: null
 })

 export default function dialog(state = initialItem, action) {
     switch(action.type) {
         case ActionTypes.DIALOG:
             return state.set("title", title).set("isVisible", action.data.isShow).set("ok", action.data.ok).set("cancel", action.data.cancel)
         default:
             return state
     }
 }

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

 import React, { Component } from 'react'
 import classNames from 'classnames'

 var DialogBox = React.createClass({
     render: function () {
         let dailogHeader = <div className="grx-modal-dialog-header">
             <input type="image" src="/static/img/dialog/close_00.png"
                 title="关闭"
                 onClick={this.props.actions.dialogAction({isShow: false})}/>
             <h5>
                 {this.state.title}
             </h5>
         </div>
         let dialogBody = <div className="grx-modal-dialog-content">
             {this.props.children}
         </div>
         let dialogFooter = <div>...</div>
         return (
             <div className="grx-modal-dialog-wrap">
                 {overlay}
                 <div className="grx-modal-dialog" style={dialogStyles}>
                     {dailogHeader}
                     {dialogBody}
                     {dialogFooter}
                 </div>
             </div>
         )
     }
 })
 export default DialogBox

====================================
组合reduce
====================================

 import { combineReducers } from 'redux'
 const reducers = combineReducers({
     form,
     items,
     dialog
 })

派发的消息,会挨个传入组合的reduce里,谁对消息感兴趣谁就接受此消息即可。
这样组件之间通过消息通讯,正所谓高内聚低媾合,组件之间不需要彼此知道彼此是谁,我只对数据感兴趣,那么数据怎么和组件关联上的呢,请看下面:

====================================
链接component和reduce
====================================

 import { bindActionCreators } from 'redux'
 import { connect } from 'react-redux'
 import * as AllActions from '../actions'
 export default connect(state => ({
     form: state.form,
     items: state.items,
     dialog: state.dialog,
 }), dispatch => ({
     actions: bindActionCreators(AllActions, dispatch)
 }))(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)阿猿们从此变的简单快乐,简单快乐,简单快乐。

野心勃勃的React组件生命周期的更多相关文章

  1. React组件生命周期小结

    React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...

  2. React—组件生命周期详解

    React—组件生命周期详解 转自 明明的博客  http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...

  3. 1.4 React 组件生命周期

    1.4.1 组件 React 中组件有自己的生命周期方法,简单理解可以为组件从 出生(实例化) -> 激活 -> 销毁 生命周期 hook.通过这些 hook 方法可以自定义组件的特性. ...

  4. React组件生命周期过程说明

    来自kiinlam github94 实例化 首次实例化 getDefaultProps getInitialState componentWillMount render componentDidM ...

  5. React组件生命周期过程说明【转】

    实例化 首次实例化 getDefaultProps getInitialState componentWillMount render componentDidMount 实例化完成后的更新 getI ...

  6. 深入React组件生命周期

    上篇博文使用React开发的一些注意要点对React开发的一些重点进行了简单的罗列总结,虽然也提到了React生命周期,但只略微小结,在此单独写篇React生命周期的总结. 在组件的整个生命周期中,随 ...

  7. 3. React 组件生命周期介绍

            React 中的每个组件都有三个阶段,这三个阶段构成了组件完整的生命周期.组件的生命周期为]); return; } this.setState({name: event.target ...

  8. react组件生命周期过程

    实例化 首次实例化 getDefaultProps getInitialState componentWillMount render componentDidMount 实例化完成后的更新 getI ...

  9. react组件生命周期

    1. Mounting/组建挂载相关 (1)componentWillMount 组件将要挂载.在render之前执行,但仅执行一次,即使多次重复渲染该组件或者改变了组件的state (2)compo ...

随机推荐

  1. npm install报错Error: ENOENT

    E:\projects\ueditor\ueditor1_4_3_3-src>npm installError: ENOENT, stat 'C:\Users\Lucas\AppData\Roa ...

  2. 从世界坐标转换成ui的rect坐标的方法

    这个东西整整折磨了我一个通宵.原谅我先这样放上来.明天整理整理 using UnityEngine; using System.Collections; using UnityEngine.UI; p ...

  3. CSS3--box-shadow

    box-shadow:属性向框添加一个或多个阴影: 语法:box-shadow:h-shadow v-shadow blur pread color inset; h-shadow:必需,水平阴影的位 ...

  4. python——操作Redis

    在使用django的websocket的时候,发现web请求和其他当前的django进程的内存是不共享的,猜测django的机制可能是每来一个web请求,就开启一个进程去与web进行交互,一次来达到利 ...

  5. 实现远程FTP特定时间轨道号MODIS数据的搜索

    private ArrayList alst = new System.Collections.ArrayList();//建立ArrayList对象 int strLength = 0; strin ...

  6. Discuz! X论坛上传附件到100%自动取消上传的原因及解决方案

    最近接到一些站长的反馈,说论坛上传附件,到100%的时候自己取消上传了.经查是附件索引表pre_forum_attachment表的aid字段自增值出现了问题,导致程序逻辑返回的aid值实际为一个My ...

  7. ASP.NET 教程(一)

    ASP.NET 是一个开发框架,用于通过 HTML.CSS.JavaScript 以及服务器脚本来构建网页和网站. ASP.NET 支持三种开发模式: Web Pages.MVC (Model Vie ...

  8. Discuz中解决jquery 冲突的方法 绝对简单

    将jquery.js在common.js之前载入,不然jquery的$()函数会覆盖common.js的$()函数: 然后用到jQuery的$()函数的地方都用jQuery()代替. 例如 $(doc ...

  9. c++读书笔记, 零散点滴的收获

    1. 字节长度: short <= int <= long <= long long 2. wchar_t,最大扩展字符集合:char16_t.char32_t,unocide字符集 ...

  10. 如何应用.NET中的消息队列服务

    建立一个队列是应用MSMQ的第一步.您可以通过Windows计算机管理控制台中的消息队列选项完成这一操作,或者自己编程建立一个队列.列表A中的C#代码建立了一个新的私有MSMQ消息队列(如果不存在队列 ...