当你还在写着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. Android 之surfaceView (画动态圆圈)

      通过之前介绍的如何自定义View, 我们知道使用它可以做一些简单的动画效果.它通过不断循环的执行View.onDraw方法,每次执行都对内部显示的图形做一些调整,我们假设 onDraw方法每秒执行 ...

  2. MySQL问题记录--python插入中文至MySQL提示SQLErroor:1366错误

    一.在爬虫脚本做以下操作仍提示错误:SQL Error: 1366: Incorrect string value: "\xd0\xc2\xce\xc5-" for column  ...

  3. css学习笔记 3

    css选择符: 通配选择符:* 类选择符:.className 标签选择符 后代选择符:例:p strong ,选择的是p标签内的所有strong标签. 子选择符:> ,只选择父标签内的直接子标 ...

  4. javac 导入第三方jar包

    如果是导入一个包,只需要 javac -classpath xxx/xxx/xxx.jar xxx.java 即可 如果有多个包,windows下用分号隔开,Lunix下用冒号隔开即可.

  5. 在引用KindEditor编辑器时,运行时出现以下错误:错误46 找不到类型或命名空间名称“LitJson”(是否缺少 using 指令或程序集引用?)

    将asp.net下bin文件夹下的文件LitJSON.dll拷贝到工程的bin目录下,并在工程中添加引用 在后台加入: using LitJson;

  6. maven webjar构建及使用

    这么做的目的想要把前端静态文件,css啊js啊一堆的放在一个maven工程下管理,需要的时候调用jar包直接引用. 1.把要打包文件放到另外的maven项目的/src/main/resources下 ...

  7. 两个div叠加触发事件发生闪烁问题

    今天遇到一个问题,想实现一个功能: 当鼠标移到div1上的时候,会出现div2.出现时div2在div1的上面,div2在出现后发生闪烁的问题. 于是开始找问题根源,发现原来是因为当我们触发div1的 ...

  8. YY前端课程-自习

    1. 默认的浏览器字体 100% = 1em  =1rem =16px  =12pt em继承父元素,rem只继承html根元素 2. text-align水平对齐影响一个元素中文本的水平对齐方式,控 ...

  9. System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题

    C#连接ORACLE报System.Data.Oracleclient需要Oracle客户端软件Version8.1.7或更高版本问题: 开始Webservice在32位系统ORACLE10g库中we ...

  10. 【转】Spring bean处理——回调函数

    Spring bean处理——回调函数 Spring中定义了三个可以用来对Spring bean或生成bean的BeanFactory进行处理的接口,InitializingBean.BeanPost ...