react.js--------js库

1.react是什么?

React是Facebook开源的一个用于构建用户界面的Javascript库,已经 应用于Facebook及旗下Instagram。css

和庞大的AngularJS不一样,React专一于MVC架构中的V,即视图。 这使得React很容易和开发者已有的开发栈进行融合。html

React顺应了Web开发组件化的趋势。应用React时,你老是应该从UI出发抽象出不一样 的组件,而后像搭积木同样把它们拼装起来前端

这个项目自己也越滚越大,从最先的UI引擎变成了一整套先后端通吃的 Web App 解决方案。衍生的 React Native 项目,目标更是宏伟,但愿用写 Web App 的方式去写 Native App。若是可以实现,整个互联网行业都会被颠覆,由于同一组人只须要写一次 UI ,就能同时运行在服务器、浏览器和手机node

英文网:http://facebook.github.io/react/docs/getting-started.htmlreact

文档最新且更新快(推荐你们看这个)jquery

中文网:http://reactjs.cn/react/docs/getting-started.htmlwebpack

文档陈旧版本低(你们若是看不懂英文能够先看这个)git

为何使用react?es6

咱们创造 React 是为了解决一个问题:构建随着时间数据不断变化的大规模应用程序。为了达到这个目标,React 采用下面两个主要的思想。github

一、简单

仅仅只要表达出你的应用程序在任一个时间点应该长的样子,而后当底层的数据变了,React 会自动处理全部用户界面的更新。

二、声明式 (Declarative)

数据变化后,React 概念上与点击“刷新”按钮相似,但仅会更新变化的部分。

三、构建可组合的组件

React 都是关于构建可复用的组件。事实上,经过 React 你惟一要作的事情就是构建组件。得益于其良好的封装性,组件使代码复用、测试和关注分离(separation of concerns)更加简单。

更多缘由 http://facebook.github.io/react/blog/2013/06/05/why-react.html

react网站案例:智客网

http://info.smartstudy.com/

http://www.kongkonghu.com/choice

https://github.com/webpack/react-starter

入门视频:

https://www.youtube.com/watch?v=7eLqKgp0eeY

https://www.youtube.com/watch?v=fZKaq623y38&list=PLQDnxXqV213JJFtDaG0aE9vqvp6Wm7nBg

https://www.youtube.com/watch?v=QQK5hpUuOuA&list=PLUAEXpf1UDMkzPOiNJBrlqsUryn7n2cnK

参考资料:

https://github.com/dingyiming/learn-Js-react/issues/1

2.react的四个概念

1.virtual DOM(实现跨平台、页面渲染速度快)

1>  虚拟DOM是React的基石。

之因此引入虚拟DOM,一方面是性能的考虑。Web应用和网站不一样,一个Web应用 中一般会在单页内有大量的DOM操做,而这些DOM操做很慢。

在React中,应用程序在虚拟DOM上操做,这让React有了优化的机会。简单说, React在每次须要渲染时,会先比较当前DOM内容和待渲染内容的差别, 而后再决定如何最优地更新DOM。这个过程被称为reconciliation。

除了性能的考虑,React引入虚拟DOM更重要的意义是提供了一种一致的开发方 式来开发服务端应用、Web应用和手机端应用:

由于有了虚拟DOM这一层,因此经过配备不一样的渲染器,就能够将虚拟DOM的内容 渲染到不一样的平台。而应用开发者,使用JavaScript就能够通吃各个平台了。

至关棒的思路!

2>Virtual DOM速度快的说明

在Web开发中,咱们总须要将变化的数据实时反应到UI上,这时就须要对DOM进行操做。而复杂或频繁的DOM操做一般是性能瓶颈产生的缘由(如何 进行高性能的复杂DOM操做一般是衡量一个前端开发人员技能的重要指标)。React为此引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API。基于React进行开发时全部的DOM构造都是经过虚拟DOM进行,每当数据变化时,React都会从新构建整个DOM树,而后React将当前 整个DOM树和上一次的DOM树进行对比,获得DOM结构的区别,而后仅仅将须要变化的部分进行实际的浏览器DOM更新。并且React可以批处理虚拟 DOM的刷新,在一个事件循环(Event Loop)内的两次数据变化会被合并,例如你连续的先将节点内容从A变成B,而后又从B变成A,React会认为UI不发生任何变化,而若是经过手动控 制,这种逻辑一般是极其复杂的。尽管每一次都须要构造完整的虚拟DOM树,可是由于虚拟DOM是内存数据,性能是极高的,而对实际DOM进行操做的仅仅是 Diff部分,于是能达到提升性能的目的。这样,在保证性能的同时,开发者将再也不须要关注某个数据的变化如何更新到一个或多个具体的DOM元素,而只须要 关心在任意一个数据状态下,整个界面是如何Render的。

http://blog.csdn.net/yczz/article/details/49585313

2.react组件

1>组件化的概念

虚拟DOM(virtual-dom)不只带来了简单的UI开发逻辑,同时也带来了组件化开发的思想,所谓组件,即封装起来的具备独立功能的UI部 件。React推荐以组件的方式去从新思考UI构成,将UI上每个功能相对独立的模块定义成组件,而后将小的组件经过组合或者嵌套的方式构成大的组件, 最终完成总体UI的构建。例如,Facebook的instagram.com整站都采用了React来开发,整个页面就是一个大的组件,其中包含了嵌套 的大量其它组件,你们有兴趣能够看下它背后的代码。

若是说MVC的思想让你作到视图-数据-控制器的分离,那么组件化的思考方式则是带来了UI功能模块之间的分离。咱们经过一个典型的Blog评论界面来看MVC和组件化开发思路的区别。

对于MVC开发模式来讲,开发者将三者定义成不一样的类,实现了表现,数据,控制的分离。开发者更多的是从技术的角度来对UI进行拆分,实现松耦合。

对于React而言,则彻底是一个新的思路,开发者从功能的角度出发,将UI分红不一样的组件,每一个组件都独立封装。

在React中,你按照界面模块天然划分的方式来组织和编写你的代码,对于评论界面而言,整个UI是一个经过小组件构成的大组件,每一个组件只关心本身部分的逻辑,彼此独立。

组件的四个特性:

    有自定义的标签

    高内聚的资源

    独立的做用域

    规范化的接口

2>组件化开发特性

React认为一个组件应该具备以下特征:

(1)可组合(Composeable):一个组件易于和其它组件一块儿使用,或者嵌套在另外一个组件内部。若是一个组件内部建立了另外一个组件,那么说父组件拥有(own)它建立的子组件,经过这个特性,一个复杂的UI能够拆分红多个简单的UI组件;

(2)可重用(Reusable):每一个组件都是具备独立功能的,它能够被使用在多个UI场景;

(3)可维护(Maintainable):每一个小的组件仅仅包含自身的逻辑,更容易被理解和维护;

(4)可测试(Testable):由于每一个组件都是独立的,那么对于各个组件分别测试显然要比对于整个UI进行测试容易的多。

3>组件定义

在React中定义一个组件也是至关的容易,组件就是一个 实现预约义接口的JavaScript类:

一、 组件渲染

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);

而这个方法, 必须并且只能返回一个有效的React元素。这意味着,若是你的组件是由多个元素构成的,那么你必须在外边包一个顶层 元素,而后返回这个顶层元素。好比咱们建立一个布局组件:

render:function(){
    return React.createElement(
        "div",null,
        React.createElement("div",null,"header"),
        React.createElement("div",null,"content"),
        React.createElement("div",null,"footer")
    );
}

二、ES5方式定义组件

"use strict";

var HelloMessage = React.createClass({
  displayName: "HelloMessage",

  render: function render() {
    return React.createElement(
      "div",
      null,
      "Hello ",
      this.props.name
    );
  }
});

ReactDOM.render(React.createElement(HelloMessage, { name: "John" }), mountNode);

三、Jsx中定义组件

var HelloMessage = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(<HelloMessage name="John" />, mountNode);

四、ES6中定义组件

import './Hello.css';
import './Hello.scss';

import React, {Component} from 'react';

// 内联样式
let style={
    backgroundColor:'blue'
}

export default class Hello extends Component {
    constructor(props) {
        super(props);
        this.state = { count: 'es6'};
    }
    render() {
        return (
            <div>
                <h1 style={style}>Hello world{this.state.count}</h1>
                <br/>
                <image/>
            </div>
        )
    }
}

五、注意事项

(1)你的React组件名称的首字母应当大写,关于大小写的差别你会在后面发现。

(2)你应该会注意到div元素的样式类是用 className而不是class声明的,这是由于class 是JavaScript的保留字,渲染后,真实的DOM还会是:

<div class="ez-led">Hello, React!</div>

3>jsx语法:

1.什么是jsx?

在用React写组件的时候,一般会用到JSX语法,粗看上去,像是在Javascript代码里直接写起了XML标签,实质上这只是一个语法糖,每个 XML标签都会被JSX转换工具转换成纯Javascript代码,固然你想直接使用纯Javascript代码写也是能够的,只是利用JSX,组件的结 构和组件之间的关系看上去更加清晰

2.jsx语法使用:

HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 JSX 的语法,它容许 HTML 与 JavaScript 的混写。

var names = ['Alice', 'Emily', 'Kate'];

ReactDOM.render(
  <div>
  {
    names.map(function (name) {
      return <div>Hello, {name}!</div>
    })
  }
  </div>,
  document.getElementById('example')
);

上面代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。

JSX 容许直接在模板插入 JavaScript 变量。若是这个变量是一个数组,则会展开这个数组的全部成员

var arr = [

  <h1>Hello world!</h1>,

  <h2>React is awesome</h2>,

];

ReactDOM.render(

  <div>{arr}</div>,

  document.getElementById('example')

);

上面代码的arr变量是一个数组,结果 JSX 会把它的全部成员,添加到模板

4>单项数据流:Data Flow

 * 1.传统的mvc

 

到了 Flux 当中, 除了名字改变了, 重要的是大量的 Model 归到了 Store, View 也统一了,从而获得了所谓单向的数据流, 就是 Model 和 View 之间关系很是清晰了。这样须要人为管理的状态就一下少了不少, 结果体如今开发应用的效率当中:

* 2.flux

一、详细学习地址:https://hulufei.gitbooks.io/react-tutorial/content/flux.html

二、React 标榜本身是 MVC 里面 V 的部分,那么 Flux 就至关于添加 M 和 C 的部分,Flux 是 Facebook 使用的一套前端应用的架构模式。

三、一个 Flux 应用主要包含四个部分:

(1)dispatcher 处理动做分发,维护 Store 之间的依赖关系

(2)stores  数据和逻辑部分

(3)views  React 组件,这一层能够看做 controller-views,做为视图同时响应用户交互

(4)actions  提供给 dispatcher 传递数据给 store

四、单向数据流

先来了解一下 Flux 的核心“单向数据流“怎么运做的:

Action -> Dispatcher -> Store -> View

更多时候 View 会经过用户交互触发 Action,因此一个简单完整的数据流相似这样:

 

整个流程以下:

  • 首先要有 action,经过定义一些 action creator 方法根据须要建立 Action 提供给 dispatcher
  • View 层经过用户交互(好比 onClick)会触发 Action
  • Dispatcher 会分发触发的 Action 给全部注册的 Store 的回调函数
  • Store 回调函数根据接收的 Action 更新自身数据以后会触发一个 change 事件通知 View 数据更改了
  • View 会监听这个 change 事件,拿到对应的新数据并调用 setState 更新组件 UI

全部的状态都由 Store 来维护,经过 Action 传递数据,构成了如上所述的单向数据流循环,因此应用中的各部分分工就至关明确,高度解耦了。

这种单向数据流使得整个系统都是透明可预测的。

 

Redux官方中文文档:http://camsong.github.io/redux-in-chinese/index.html

Reflux:https://segmentfault.com/a/1190000002793786?utm_source=tuicool

3.react快速开始学习:

1.建立项目文件夹

npm  init // 初始化npm配置文件

2.依赖环境

在项目根目录下打开命令窗口下载react和react-dom依赖

npm install  react  react-dom --save

3.建立目录结构

4.简单的hello world     demo

看官网英文官网的:http://facebook.github.io/react/index.html

Var React=require(‘react’);
Var ReactDOM=require(‘react-dom’);
var HelloMessage = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

ReactDOM.render(<HelloMessage name="John" />, mountNode);

5.代码的编译方式(语法转换)

由于如今都是使用jsx和es6,因此咱们须要对js代码进行编译。

编译转换有分为浏览器中转换和离线转换,可是基本上公司不会用在浏览器中引入转换js转换,因此咱们只介绍离线转换

  1>react-tools转换  

     这是react本身提供的,并且是老版本的,由于中文官网仍是老版本的api,因此介绍的是这种方式。

npm install -g react-tools // 首先安装依赖

jsx  --watch  src/  build/  // 用命令进行转换,有兴趣的你们本身看一下jsx -h


参考地址:http://reactjs.cn/react/docs/getting-started.html

  2>babel转换 

       英文官网的文档比较新,已经推荐使用babel来进行转换   

      一、下载依赖  

npm install --global babel-cli   // 安装babel

npm install babel-preset-react  -dev-save// 安装babel转换jsx的包

npm install babel-preset-es2015 -dev-save// 安装babel转化ES6的包

注意:加了-dev以后,运行npm install不会下载开发依赖,你须要运行

npm install –dev  //从github上下载以后运行这句才能下载开发依赖

      二、运行命令进行编译

babel --presets react src --watch --out-dir build  // 更多命令可运行babel –h查看或者官网

     三、将编译以后的js文件在index.html文件中引入

  3>gulp-react

          https://github.com/sindresorhus/gulp-react

  4>webpack(我用这种)

4.主要知识内容

1>视图相关概念

  • Props(属性,就是element上的attrs,换个名字property,变成复数,即props)
  • State(写过view组件的基本都会知道,按钮有三态,Normal,Highlight,Selected,包括extjs,jquery里的大部分ui框架都是有状态的。)
  • Event(其实还应该算一个就是dom事件,上面的例子就把onChange的handler编译后的handleChange方法,这要感谢jsx)

了解了上面这些,就能够写代码了,由于

  • 属性,解决了view的定义问题,即语义描述
  • 状态,是view的有穷状态机,根据状态决定组件ui和行为
  • 事件,是view里元素的行为

有穷状态机:http://baike.baidu.com/view/115336.htm

2 >   jsx语法详解

<1>HTML 转义(了解)

React 会将全部要显示到 DOM 的字符串转义,防止 XSS。因此若是 JSX 中含有转义后的实体字符好比 &copy; (©) 最后显示到 DOM 中不会正确显示,由于 React 自动把 &copy; 中的特殊字符转义了。有几种解决办法:

  • 直接使用 UTF-8 字符 ©
  • 使用对应字符的 Unicode 编码
  • 使用数组组装 <div>{['cc ', <span>&copy;</span>, ' 2015']}</div>
  • 直接插入原始的 HTML

<div dangerouslySetInnerHTML={{__html: 'cc &copy; 2015'}} />

dangerouslySetInnerHTML参考文档

http://reactjs.cn/react/tips/dangerously-set-inner-html.html

<2>自定义 HTML 属性(了解)

若是在 JSX 中使用的属性不存在于 HTML 的规范中,这个属性会被忽略。若是要使用自定义属性,能够用 data- 前缀。文档估计有问题

可访问性属性的前缀 aria- 也是支持的。

与dom的区别文档:http://reactjs.cn/react/docs/dom-differences.html

<3>支持的标签和属性

若是你要使用的某些标签或属性不在这些支持列表里面就可能被 React 忽略,必需要使用的话能够提 issue,或者用前面提到的 dangerouslySetInnerHTML

支持列表:http://reactjs.cn/react/docs/tags-and-attributes.html

一、并非全部的html标签和属性都能在jsx语法中使用

二、基本上你能用到的标签的属性,jsx语法都支持

三、有些特殊的属性须要注意,必须class属性要变为className属性

全部的属性都是驼峰命名的,class 属性和 for 属性分别改成 classNamehtmlFor来符合 DOM API 规范。

<4>属性扩散

有时候你须要给组件设置多个属性,你不想一个个写下这些属性,或者有时候你甚至不知道这些属性的名称,这时候 spread attributes 的功能就颇有用了。

var props = {};

props.foo = x;

props.bar = y;

var component = <Component {...props} />;

属性也能够被覆盖,写在后面的属性值会覆盖前面的属性。

var props = { foo: 'default' };

var component = <Component {...props} foo={'override'} />;

console.log(component.props.foo); // 'override'

<5> 自闭合标签(组件标签可使用单闭合标签也可使用双闭合标签)

若是只有一个组件,就用单闭合标签形式,若是有多个组件嵌套就用双闭合标签形式

http://reactjs.cn/react/tips/self-closing-tag.html

<6> 注释

在 JSX 里使用注释也很简单,就是沿用 JavaScript,惟一要注意的是在一个组件的子元素位置使用注释要用 {} 包起来

var content = (

  <Nav>

      {/* child comment, put {} around */}

      <Person

        /* multi

           line

           comment */

        name={window.isLoggedIn ? window.name : ''} // end of line comment

      />

  </Nav>

);

3>React的API

<1>    顶层API

http://facebook.github.io/react/docs/top-level-api.html

<2>    组件API

http://facebook.github.io/react/docs/component-api.html

4>组件的生命周期(特别重要)

组件的生命周期,另外的名字是状态回调,和上面讲的状态的惟一差异,上面的状态是它里面的元素,而组件的生命周期是它本身

https://hulufei.gitbooks.io/react-tutorial/content/component-lifecycle.html

<1>    组件的生命周期分红三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被从新渲染
  • Unmounting:已移出真实 DOM

<2>    处理函数

React 为每一个状态都提供了两种处理函数,will函数在进入状态以前调用,did 函数在进入状态以后调用,三种状态共计五种处理函数。

  • componentWillMount()
  • componentDidMount()
  • componentWillUpdate(object nextProps, object nextState)
  • componentDidUpdate(object prevProps, object prevState)
  • componentWillUnmount()

此外,React 还提供两种特殊状态的处理函数。

  • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
  • shouldComponentUpdate(object nextProps, object nextState):组件判断是否从新渲染时调用

<3>    函数调用顺序图

 

 

从上图中咱们能够看出来,组件再初始化一次以后就不会再运行上图运行中文字以上的方法,反而里面会有事件监听,从而执行shouleComponentUpdate事件。

<4>代码使用

ES5写法

var Hello = React.createClass({

    getInitialState() {

        return { liked: false };

    },

    render: function() {

        console.log(this.state.liked);

        return(

            <div>

                <h1 style={style}>Hello world</h1>

                <br/>

                <image/>

            </div>

        )

    }

});

module.exports=Hello;

ES6写法

export default class Hello extends Component {

    constructor(props) {

        super(props);


        this.state = { count: 'es6'};

    }

    render() {

        return (

            <div>

                <h1 style={style}>Hello world{this.state.count}</h1>

                <br/>

                <image/>

            </div>

        )

    }

}

<5> 参考文章

生命周期详细介绍:http://www.cnblogs.com/CHONGCHONG2008/p/5099483.html

http://reactjs.cn/react/docs/component-specs.html

<6>注意点

在ES6中用ES5的写法会报错

5>ES5/ES6最新写法对照表

React的:

http://www.tuicool.com/articles/equ2my

ReactNative的

http://bbs.reactnative.cn/topic/15/react-react-native-%E7%9A%84es5-es6%E5%86%99%E6%B3%95%E5%AF%B9%E7%85%A7%E8%A1%A8/2

6>事件处理

<1> 使用

onClick这种进行驼峰命名ES5和ES6的写法不同,在ES6中要用bind方法绑定this(具体可参照ES5和ES6写法对照表)

import React, { Component } from 'react';
import { render } from 'react-dom';

export default class LinkButton extends Component {
    constructor(props) {
        super(props);
        this.state = {liked: false};
    }

    handleClick(e) {
        this.setState({ liked: !this.state.liked });
    }

    render() {
        const text = this.state.liked ? 'like' : 'haven\'t liked';
        return (
            <p onClick={this.handleClick.bind(this)}>
                You {text} this. Click to toggle.
            </p>
        );
    }
}

<2>参数传递

ES6写法:给事件处理函数传递额外参数的方式:bind(this, arg1, arg2, ...)

render: function() {

    return <p onClick={this.handleClick.bind(this, param1,param2,param3)}>;

},

handleClick: function(param1,param2,param3, event) {

    // handle click

}

<3>React 支持的事件列表

http://reactjs.cn/react/docs/events.html

7>Dom操做

<1>方法一:findDOMNode()方法(了解)

首先咱们要了解 ReactDOM.render 组件返回的是对组件的引用也就是组件实例(对于无状态状态组件来讲返回 null),注意 JSX 返回的不是组件实例,它只是一个 ReactElement 对象。

当组件加载到页面上以后(mounted),你均可以经过 react-dom 提供的 findDOMNode() 方法拿到组件对应的 DOM 元素。

import { findDOMNode } from 'react-dom';

// Inside Component class

componentDidMound() {

  const el = findDOMNode(this);

}

findDOMNode() 不能用在无状态组件上。

<2>方法二:refs属性

另一种方式就是经过在要引用的 DOM 元素上面设置一个 ref 属性指定一个名称,而后经过 this.refs.name 来访问对应的 DOM 元素。

若是 ref 是设置在原生 HTML 元素上,它拿到的就是 DOM 元素,若是设置在自定义组件上,它拿到的就是组件实例,这时候就须要经过 findDOMNode 来拿到组件的 DOM 元素。

由于无状态组件没有实例,因此 ref 不能设置在无状态组件上,通常来讲这没什么问题,由于无状态组件没有实例方法,不须要 ref 去拿实例调用相关的方法,可是若是想要拿无状态组件的 DOM 元素的时候,就须要用一个状态组件封装一层,而后经过 reffindDOMNode 去获取。

import React, { Component } from 'react';

export default class MyInputFocus extends Component {
    constructor(props) {
        super(props);
        this.state={ userInput: '' };
    }

    handleChange(e) {
        console.log(this.refs.theInput.value);
        this.setState({ userInput: e.target.value });
    }

    clearAndFocusInput() {
        this.setState({ userInput: '' }, () => {
            this.refs.theInput.focus();
        });
    }

    render() {
        return (
            <div>
                <div onClick={this.clearAndFocusInput.bind(this)}>
                    Click to Focus and Reset
                </div>
                <input
                    ref="theInput"
                    value={this.state.userInput}
                    onChange={this.handleChange.bind(this)}
                />
            </div>
        );
    }
}

MyInputFocus.defaultProps={
    autoPlay:false,
    maxLoops:10,
}
MyInputFocus.propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
}

<3>注意事项

  • 你可使用 ref 到的组件定义的任何公共方法,好比 this.refs.myTypeahead.reset()
  • Refs 是访问到组件内部 DOM 节点惟一可靠的方法
  • Refs 会自动销毁对子组件的引用(当子组件删除时)
  • 不要在 render 或者 render 以前访问 refs
  • 不要滥用 refs,好比只是用它来按照传统的方式操做界面 UI:找到 DOM -> 更新 DOM

8>和其余库配合使用

http://reactjs.cn/react/tips/use-react-with-other-libraries.html

9>组件的 DOM 事件监听

这篇文章是讲如何给 DOM 元素绑定 React 未提供的事件

var Box = React.createClass({

  getInitialState: function() {

    return {windowWidth: window.innerWidth};

  },

  handleResize: function(e) {

    this.setState({windowWidth: window.innerWidth});

  },
  componentDidMount: function() {

    window.addEventListener('resize', this.handleResize);

  },
  componentWillUnmount: function() {

    window.removeEventListener('resize', this.handleResize);

  },

  render: function() {

    return <div>Current window width: {this.state.windowWidth}</div>;
  }
});
React.render(<Box />, mountNode);

http://reactjs.cn/react/tips/dom-event-listeners.html

一、注意添加dom事件的位置

二、在组件退出的时候,取消监听事件

10>数据获取

http://facebook.github.io/react/tips/initial-ajax.html

11>表单

表单不一样于其余 HTML 元素,由于它要响应用户的交互,显示不一样的状态,因此在 React 里面会有点特殊。

<1>状态属性

表单元素有这么几种属于状态的属性:

  • value,对应 <input> 和 <textarea> 全部
  • checked,对应类型为 checkbox 和 radio 的 <input> 全部
  • selected,对应 <option> 全部

在 HTML 中 <textarea> 的值能够由子节点(文本)赋值,可是在 React 中,要用 value 来设置。

表单元素包含以上任意一种状态属性都支持 onChange 事件监听状态值的更改。

针对这些状态属性不一样的处理策略,表单元素在 React 里面有两种表现形式。

<2>受控组件

对于设置了上面提到的对应“状态属性“值的表单元素就是受控表单组件,好比:

render: function() {

    return <input type="text" value="hello"/>;

}

一个受控的表单组件,它全部状态属性更改涉及 UI 的变动都由 React 来控制(状态属性绑定 UI)。好比上面代码里的 <input> 输入框,用户输入内容,用户输入的内容不会显示(输入框老是显示状态属性 value 的值 hello),这有点颠覆咱们的认知了,因此说这是受控组件,不是原来默认的表单元素了。

若是你但愿输入的内容反馈到输入框,就要用 onChange 事件改变状态属性 value 的值:

getInitialState: function() {

    return {value: 'hello'};

},

handleChange: function(event) {

    this.setState({value: event.target.value});

},

render: function() {

    var value = this.state.value;

    return <input type="text" value={value} onChange={this.handleChange} />;

}

使用这种模式很是容易实现相似对用户输入的验证,或者对用户交互作额外的处理,好比截断最多输入140个字符:

handleChange: function(event) {

    this.setState({value: event.target.value.substr(0, 140)});

}

<3>非受控属性

和受控组件相对,若是表单元素没有设置本身的“状态属性”,或者属性值设置为 null,这时候就是非受控组件。

它的表现就符合普通的表单元素,正常响应用户的操做。

一样,你也能够绑定 onChange 事件处理交互。

若是你想要给“状态属性”设置默认值,就要用 React 提供的特殊属性 defaultValue,对于 checked 会有 defaultChecked,<option> 也是使用 defaultValue。

<4>为何要有受控组件

引入受控组件不是说它有什么好处,而是由于 React 的 UI 渲染机制,对于表单元素不得不引入这一特殊的处理方式。

在浏览器 DOM 里面是有区分 attributeproperty 的。attribute 是在 HTML 里指定的属性,而每一个 HTML 元素在 JS 对应是一个 DOM 节点对象,这个对象拥有的属性就是 property(能够在 console 里展开一个 DOM 节点对象看一下,HTML attributes 只是对应其中的一部分属性),attribute 对应的 property 会从 attribute 拿到初始值,有些会有相同的名称,可是有些名称会不同,好比 attribute class 对应的 property 就是 className。(详细解释:.prop.prop() vs .attr()

回到 React 里的 <input> 输入框,当用户输入内容的时候,输入框的 value property 会改变,可是 value attribute 依然会是 HTML 上指定的值(attribute 要用 setAttribute 去更改)。

React 组件必须呈现这个组件的状态视图,这个视图 HTML 是由 render 生成,因此对于

render: function() {

    return <input type="text" value="hello"/>;

}

在任意时刻,这个视图老是返回一个显示 hello 的输入框。

<5>   <select>的处理

在 HTML 中 <select> 标签指定选中项都是经过对应 <option>selected 属性来作的,可是在 React 修改为统一使用 value

因此没有一个 selected的状态属性。

<select value="B">

    <option value="A">Apple</option>

    <option value="B">Banana</option>

    <option value="C">Cranberry</option>

</select>

你能够经过传递一个数组指定多个选中项:<select multiple={true} value={['B', 'C']}>

12>参数传递的判断

http://facebook.github.io/react/docs/transferring-props.html

13>组合组件

使用组件的目的就是经过构建模块化的组件,相互组合组件最后组装成一个复杂的应用。

在 React 组件中要包含其余组件做为子组件,只须要把组件看成一个 DOM 元素引入就能够了。

http://reactjs.cn/react/docs/multiple-components.html

<1>   循环插入子元素

若是组件中包含经过循环插入的子元素,为了保证从新渲染 UI 的时候可以正确显示这些子元素,每一个元素都须要经过一个特殊的 key 属性指定一个惟一值。为了内部 diff 的效率。

var TodoList = React.createClass({

    render: function() {

        var createItem = function(item) {

            return <li key={item.id}>{item.text}</li>;

        };

        return <ul>{this.props.items.map(createItem)}</ul>;

    }

});

module.export=TodoList

(1)当 React 校订带有 key 的子级时,它会确保它们被从新排序(而不是破坏)或者删除(而不是重用)。 务必key 添加到子级数组里组件自己上,而不是每一个子级内部最外层 HTML 上。

(2)也能够传递 object 来作有 key 的子级。object 的 key 会被看成每一个组件的 key。可是必定要牢记 JavaScript 并不老是保证属性的顺序会被保留。实际状况下浏览器通常会保留属性的顺序,除了 使用 32位无符号数字作为 key 的属性。数字型属性会按大小排序而且排在其它属性前面。一旦发生这种状况,React 渲染组件的顺序就是混乱。可能在 key 前面加一个字符串前缀来避免:

render: function() {

    var items = {};
    this.props.results.forEach(function(result) {

      // 若是 result.id 看起来是一个数字(好比短哈希),那么

      // 对象字面量的顺序就得不到保证。这种状况下,须要添加前缀

      // 来确保 key 是字符串。

      items['result-' + result.id] = <li>{result.text}</li>;

    });
    return (
      <ol>
        {items}
      </ol>
    );
  }

<2>子级

组件标签里面包含的子元素会经过父元素的props.children 传递进来。

HTML 元素会做为 React 组件对象、JS 表达式结果是一个文字节点,都会存入 Parent 组件的 props.children

props.children 一般是一个组件对象的数组,可是当只有一个子元素的时候,props.children 将是这个惟一的子元素,而不是数组了

var NotesList = React.createClass({

  render: function() {

    return (

      <ol>

      {

        React.Children.map(this.props.children, function (child) {

          return <li>{child}</li>;

        })

      }

      </ol>

    );

  }

}); 

ReactDOM.render(

  <NotesList>

    <span>hello</span>

    <span>world</span>

  </NotesList>,

  document.body

);

上面代码的 NoteList 组件有两个 span 子节点,它们均可以经过 this.props.children 读取,运行结果以下。

 

这里须要注意, this.props.children 的值有三种可能:若是当前组件没有子节点,它就是 undefined ;若是有一个子节点,数据类型是 object ;若是有多个子节点,数据类型就是 array 。因此,处理 this.props.children 的时候要当心。

React 提供一个工具方法 React.Children 来处理 this.props.children 。咱们能够用 React.Children.map 来遍历子节点,而不用担忧 this.props.children 的数据类型是 undefined 仍是 object。更多的 React.Children 的方法,请参考官方文档

14>propsType

http://www.reactjs.cn/react/docs/reusable-components.html

15>Context

http://facebook.github.io/react/docs/context.html

16>动画

http://facebook.github.io/react/docs/animation.html

http://blog.csdn.net/lihongxun945/article/details/46778723

https://zhuanlan.zhihu.com/p/20419592

17>获取react经常使用插件的网址

https://js.coach/react/react-infinite

https://react.parts/native

18>diff算法

http://blog.csdn.net/lihongxun945/article/details/46640503

http://reactjs.cn/react/docs/reconciliation.html

http://blog.csdn.net/yczz/article/details/49585283

http://blog.csdn.net/yczz/article/details/49886061

19>Web Components

http://www.oschina.net/p/polymer

http://facebook.github.io/react/docs/webcomponents.html

20>服务器渲染

http://zhuanlan.zhihu.com/p/20669111?from=groupmessage&isappinstalled=0

21>组件间通讯

<1>非父子组件间的通讯

使用全局事件 Pub/Sub 模式,在 componentDidMount 里面订阅事件,在 componentWillUnmount 里面取消订阅,当收到事件触发的时候调用 setState 更新 UI。

这种模式在复杂的系统里面可能会变得难以维护,因此看我的权衡是否将组件封装到大的组件,甚至整个页面或者应用就封装到一个组件。

通常来讲,对于比较复杂的应用,推荐使用相似 Flux 这种单项数据流架构,参见Data Flow。Flux和redux

<2>数据流Flux

Github地址:https://github.com/facebook/flux

React   redux  react-redux   react-router     webpack+gulp  ES6  babel

Mocha+chai  node

 React native  Flex  fetch  原生  找插件

 

22>react-router

<1>学习网址

github地址:https://github.com/reactjs/react-router           

最好是去github上看文档,由于随着时间的推移,版本的变动,市面上的一些文档已经没有及时性和准确性了。Github上已经有好几个版本的了,咱们学习最新版本的。之后若是有问题先检查版本是否是升级致使的问题。

gitbook地址:http://react-guide.github.io/react-router-cn/

https://segmentfault.com/a/1190000006063554

<2>react-router简介

React Router 是一个基于 React之上的强大路由库,它可让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。

<3>以前页面跳转的实现(了解)

http://react-guide.github.io/react-router-cn/docs/Introduction.html

<4>基础配置

一、他会把route的第一个组件加载到根组件的this.chileren里面

二、下面这种写法会报错

<a><Link to="/indox/messages/1">message</Link></a>

三、刷新的错误

 React-router升级说明

2.X https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#no-default-history

History文档

https://github.com/mjackson/history

 

 

利用reauest模块实现服务代理:

 

 

 利用fetch获取数据:

 

相关文章
相关标签/搜索