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獲取數據:

 

相關文章
相關標籤/搜索