react初探

本文是我学习react的阶段性小结,若是看官你是react资深玩家,那么还请就此打住移步他处,若是你想给一些建议和指导,那么还请轻拍~html

目前团队内对react的使用很是广泛,以前对react使用很少,正好我目前在作的项目也在使用react+redux,借着这个机会系统的学习下react+redux。前端

react是什么

react是一个JavaScript类库,经过react,咱们能够构建可组合的UI,也就是说,咱们能够经过重用组件来组合出咱们的UI。能够说react的核心即是组件,目的就是重用和组合。react

react解决什么问题

官网有这样一句话.git

We built React to solve one problem: building large applications with data that changes over time.github

咱们知道,随着应用规模的不断扩大,UI背后的数据模型愈来愈复杂,业务逻辑也不可避免的变得愈来愈复杂,以致于复杂到仅仅是修复一个简单的问题咱们就须要投入大量的时间和精力。编程

现有的不少前端框架都在致力于解决这样的问题,基本思想都是基于MV*的模式,这里有一篇文章详细介绍了各类MV*模式的原理和优缺点。redux

那么,react是如何解决这个问题的呢?
react聚焦于组件。react理解的组件实际上就是一个状态机。当组件处于某个状态时,就输出这个状态对应的界面。在React中,咱们只须要简单的去更新某个组件的状态,而后输出基于新状态的整个界面。React负责以最高效的方式去比较两个界面并更新DOM树。至于如何对组件以外的数据进行管理,react提出了flux方案。segmentfault

react点点点

生命周期

前面咱们知道,react组件是一个状态机器,以状态为输入,以界面为输出。在不一样状态切换之间,react提供了一系列的生命周期方法,大体能够分为以下三类:api

实例化时期

react组件在实例化时会依次调用以下组件方法:前端框架

  • getDefaultProps
  • getInitialState
  • componentWillMount
  • render
  • componentDidMount

存在期

当react组件被实例化后,用户的一些操做会致使组件状态的更新,此时以下方法将依次被调用:

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

销毁时期

在组件销毁的时候,会调用以下组件方法:

  • componentWillUnmount

这里有一段简单的测试代码:

var ChildComponent = React.createClass({
    render: function () {
        console.log("call render");
        return (
            <div>
                {this.props.data}
            </div>
        );
    },
    componentWillReceiveProps: function () {
        console.log("call componentWillReceiveProps");
    },
    shouldComponentUpdate: function () {
        console.log("call shouldComponentUpdate");
        return true;
    },
    componentWillUpdate: function () {
        console.log("call componentWillUpdate");
    },
    componentDidUpdate: function () {
        console.log("call componentDidUpdate");
    },
    componentWillUnmount: function () {
        console.log("call componentWillUnmount");
    }
});
var MyComponent = React.createClass( {
    getDefaultProps: function () {
        // console.log("call getDefaultProps");
        return {
            className: "test"
        };
    },
    getInitialState: function () {
        // console.log("call getInitialState");
        // console.log("log prop: ", this.props);
        return {
            text: "something"
        };
    },
    componentWillMount: function () {
        console.log("call componentWillMount");
    },
    componentDidMount: function () {
        console.log("call componentDidMount");
    },
    render: function () {
        console.log("call render");
        var child;
        if (this.state.text === "after click") {
            child = null;
        } else {
            child = <ChildComponent data={this.state.text} />;
        }
        return (
            <div className={this.props.className} onClick={this.handleClick}>
                {child}
            </div>
        );
    },
    handleClick: function () {
        this.setState({
            text: "after click"
        });
    }
});
ReactDOM.render(
    <MyComponent />,
    document.getElementById("content")
);

经常使用API

关于API的部分,官网已经给了详尽的说明,此处略去。

JSX

JSX是react的核心组件之一。react坚信标签和生成它的代码是紧密相连的,若是展现逻辑很是复杂(事实上大多数状况下都是),那么经过模板语言来实现这些逻辑会产生大量代码,因而react作了一个很是简单、可选相似HTML语法 ,经过函数调用便可生成模板的编译器,称为JSX。

经过JSX,咱们能够用HTML的语法建立JavaScript对象。好比,为了在React中生成一个连接,经过纯JavaScript能够这么写:

React.createElement('a', {href: 'http://facebook.github.io/react/'}, 'Hello React!')

经过JSX这就变成了:

<a href="http://facebook.github.io/react/">Hello React!</a>

咱们发现经过JSX,代码会更加简洁和易读,使用起来也更加方便。

更过关于JSX的内容请参考官方文档.

组合可重用的组件

前面咱们知道,react的核心就是组件,目的就是重用和组合。那么咱们如何才能作到组件可重用和组合呢?

首先说说组合。
组合描述的是一种从属关系,在面向对象编程中被描述为HAS-A的关系。
在react中,咱们经过以下的代码实现组合:

<Parent><Child data={this.props.childData} /></Parent>

在这个例子中,Parent中有一个Child的实例,Parent是拥有着。在组件中,组件不能改变自身的props,组件的props始终与组件的拥有着设置的保持一致。
这里就有一个很是有趣的事情。组件的props永远来自于组件的拥有者(默认的除外),组件的拥有者能够经过它的props 或state计算出一些值,并把这些值绑定到它们拥有的组件的props上,即在react中,数据就经过props的方式从组件的拥有者单向的流向了组件。

再说说可重用。
可重用,第一感受就是有一层抽象含义在其中。咱们从若干类似的组件中抽象出一层接口,实现公共的组件。换句话说,咱们把一些页面上通用的设计元素(按钮、表单等)拆分红接口设计良好的可复用组件。每个组件通过良好的测试和封装,那么在下次开发类似的页面的时候,能够写更少的代码,也意味着更高的开发效率和更高的质量。

更多关于组件组合和可重用的说明,请参考复合组件可重用组件

单向数据流与redux

前面知道,react关注组件,组件的状态发生变化,react会更新页面dom,在这其中缺失了对数据的管理。当应用的规模愈来愈大,咱们面临的挑战正是来源于对数据的管理和页面的更新。如今react解决了页面更新的问题,那么数据管理如何解决呢?

react提出“单向数据流”的概念,并在此基础上推出flux应用体系架构。
Flux应用主要包括三部分:dispatcher、store和views(React components)。Dispatcher,stores和views是拥有清晰的输入输出的独立节点,而actions是包含了新的数据和身份属性的简单对象。当用户与React视图交互的时候,视图会经过中枢dispatcher产生一个action。而后大量的保存着应用数据和业务逻辑的视图接收到冒泡的action,更新全部受影响的view。

下图是flux的结构图:
flux
原图来自react官网

说到flux,就不得不提redux了,这里贴几篇关于flux、reflux和redux的对比文章。

也贴一张redux的结构图吧:
redux
原图来自《UNIDIRECTIONAL USER INTERFACE ARCHITECTURES》

我的感受,redux作了更加完善的封装,开发者不用过多的关注action怎么dispatch到store那里,也不用关注store如何触发更新view的逻辑,开发者须要作的就是根据本身的实际需求,知道何时产生什么样的action以及如何处理这些action就能够了,其余的就交给redux吧~

相关文章
相关标签/搜索