React介紹(講人話)

React 背景知識html

  React 是一個用於構建用戶界面的 JavaScript 庫,主要用於構建 UI,而不是一個 MVC 框架,但可使用 React 做爲 MVC 架構的 View 層輕易的在已有項目中使用,它是一個用於構建用戶界面的 JavaScript 庫,起源於 Facebook 的內部項目,用來架設 Instagram 的網站,於 2013 年 5 月開源。React 擁有較高的性能,代碼邏輯很是簡單,愈來愈多的人已開始關注和使用它。前端

  之前沒有 ajax 技術的時候,web 頁面從服務端總體渲染出 html 輸出到瀏覽器端進行渲染,一樣的,用戶的一個改變頁面的操做也會刷新整個頁面來完成。直到有了 ajax 出現,實現頁面局部刷新,帶來的高效和分離讓 web 開發者們驚歎不已。但隨之而來的問題是,複雜的用戶交互及展示須要經過大量的 DOM 操做來完成,這讓頁面的性能以及開發的效率又出現了新的瓶頸。react

  時至今日,談到前端性能優化,減小 DOM 元素、減小 reflow 和 repaint、編碼過程當中儘可能減小 DOM 的查詢等手段是你們耳熟能詳的。而頁面任何UI的變化都是經過總體刷新來完成的。幸運的是,React 經過本身實現的 DOM Diff 算法,計算出虛擬頁面當前版本和新版本之間的差別,最小化重繪,避免沒必要要的 DOM 操做,解決了這兩個公認的前端性能瓶頸,實現高效 DOM 渲染。git

  咱們知道,頻繁的操做 DOM 所帶來的性能消耗是很大的,而 React 之因此快,是由於它不直接操做 DOM,而是引進虛擬 DOM 的實現來解決這個問題github

  對於頁面的更新,React 經過本身實現的 DOM Diff 算法來進行差別對比、差別更新,反映到頁面上就是隻重繪了更新的部分,從而提升渲染效率。web

備註:如下性能闡述參考自尤雨溪。ajax

  對於 React 的性能方面,想囉嗦幾句:算法

    1. React 歷來沒有說過 「React 比原生操做 DOM 快」。React 的基本思惟模式是每次有變更就整個從新渲染整個應用。若是沒有 Virtual DOM,簡單來說就是直接重置 innerHTML。編程

    2. 在比較性能的時候,要分清楚初始渲染、小量數據更新、大量數據更新這些不一樣的場合。數組

    3. 不要天真地覺得 Virtual DOM 就是快,diff 不是免費的,Virtual DOM 真正的價值歷來都不是性能,而是它 

      1) 爲函數式的 UI 編程方式打開了大門;

      2) 能夠渲染到 DOM 之外的其餘場景,如 backend、native。

組件化

  在業務開發中,遇到公共的模板部分,咱們不得不將模板和規定的數據格式耦合在一塊兒來實現組件。而在 React 中,咱們可使用 JSX 語法來封裝組件,將組件的結構、數據邏輯甚至樣式都聚合在一塊兒,更加簡單、明瞭、直觀的定義組件。

  有了組件化的實現,咱們能夠很直觀的將一個複雜的頁面分割成若干個獨立組件,再將這些獨立組件組合完成一個複雜的頁面。這樣既減小了邏輯複雜度,又實現了代碼的重用。

React 基礎

模板

<!DOCTYPE html><html><head><script src=「js/react.js」></script><script src=「js/react-dom.js」></script><script src=「js/browser.min.js」></script></head><body><div id=「example」></div><script type=「text/babel」>/*
    
    * ReactDOM.render 是 React 的最基本方法,用於將模板轉爲 HTML 語言,

    * 並插入指定的 DOM 節點。

    * 
    */
 
        ReactDOM.render(

            <h1>Hello, 博看文思!</h1>,
            document.getElementById(‘example’)

        );

        </script></body></html>            

JSX

  上一節的代碼, HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它容許 HTML 與 JavaScript 的混寫

JSX的好處:

1.使用JSX語法來封裝組件有什麼好處:

  1)熟悉的代碼

  2)更加語義化

  3)更加抽象且直觀

2.幾個注意點:

  1)render的方法中return的頂級元素只能是一個;

  2)若是要定義樣式的時候,不能這樣去寫
    // 不要出現相似的錯誤,style=「opacity:{this.state.opacity};」

  3)使用 className 和 htmlFor 來替代對應的class 和 for

提示:關於組件化的話題,感興趣的話能夠繼續關注Vuejs、Web components等對組件的寫法。/**隨着更爲複雜的多端環境的出現,組件標準化還有着更大的想象空間,React的組件定義不是終點,也不必定是標準,但會在組件化的道路上留下深入de影響。**/

JSX 基本語法:

    var names = [‘Alice’, ‘Emily’, ‘Kate’];


    ReactDOM.render(

        <div>

        {
    
        names.map(function (name,key) {

            return <div key={key}>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’)

);

組件

1.概念

  React 容許將代碼封裝成組件(component),而後像插入普通 HTML 標籤同樣,在網頁中插入這個組件。React.createClass 方法就用於生成一個組件類 

2.代碼示例

var HelloMessage = React.createClass({

    render: function() {

        return <h1>Hello {this.props.name}</h1>;

    }

});


ReactDOM.render(

    <HelloMessage name=「John」 />,
 
    document.getElementById(‘example’)

);

 

var HelloMessage = React.createClass({

 render: function() {

return <h1 className=「green」>Hello {this.props.name}</h1>;

 }

});


ReactDOM.render(

  <HelloMessage name=「John」 />,

document.getElementById(‘example’)

);

this.props.children

this.props 對象的屬性與組件的屬性一一對應,可是有一個例外,就是 this.props.children 屬性。它表示組件的全部子節點

var NotesList = React.createClass({
    render: function() {
        return (
        <ol>
        {
            /*
            * 由於this.props.children的返回值會根據子節點的數量返回undefined,object,array.
            * 因此react提供了一個react.Children的方法專門處理this.props.children
            * */
            React.Children.map(this.props.children, function (child) {
                return <li>{child}</li>;
            })
        }
        </ol>
        );
    }
});
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
        document.getElementById(「example」)
);

 PropTypes

組件的屬性能夠接受任意值,字符串、對象、函數等等均可以。有時,咱們須要一種機制,驗證別人使用組件時,提供的參數是否符合要求。組件類的PropTypes屬性,就是用來驗證組件實例的屬性是否符合要求。

var MyTitle = React.createClass({
    propTypes: {
        /*
        * 聲明title屬性是必須的,而且數據類型要爲字符串,至關因而規範化的接口文檔
        * */
        title: React.PropTypes.string.isRequired,
    },
    render: function() {
        return <h1> {this.props.title} </h1>;
    }
});
var data = 「123」;
ReactDOM.render(
    <MyTitle title={data} />,
        document.getElementById(「example」)
);

 

   錯誤示範:

var data = 123;
ReactDOM.render(
  <MyTitle title={data} />,
  document.body
);

 

getDefaultProps

getDefaultProps 方法能夠用來設置組件屬性的默認值

var MyTitle = React.createClass({
        getDefaultProps: function () {
            return {
                title:」hello world」
            }
        },
        render: function() {
            return <h1> {this.props.title} </h1>;
        }
    });
//    var data = 「123」;
    ReactDOM.render(
        <MyTitle />,
            document.getElementById(「example」)
    );

  獲取真實的 DOM 節點

  組件並非真實的 DOM 節點,而是存在於內存之中的一種數據結構,叫作虛擬 DOM (virtual DOM)。只有當它插入文檔之後,纔會變成真實的 DOM 。根據 React 的設計,全部的 DOM 變更,都先在虛擬 DOM 上發生,而後再將實際發生變更的部分,反映在真實 DOM上,這種算法叫作 DOM diff ,它能夠極大提升網頁的性能表現。

var MyComponent = React.createClass({
    handleClick: function() {
        this.refs.myTextInput.focus();
    },
    render: function() {
        return (
        <div>
        <input type=「text」 ref=「myTextInput」 />
        <input type=「button」 value=「Focus the text input」 onClick={this.handleClick} />
        </div>
        );
    }
});

ReactDOM.render(
<MyComponent />,
        document.getElementById(‘example’)
);

  this.state

   組件免不了要與用戶互動,React 的一大創新,就是將組件當作是一個狀態機,一開始有一個初始狀態,而後用戶互動,致使狀態變化,從而觸發從新渲染 UI。React 把組件當作是一個狀態機(State Machines)。經過與用戶的交互,實現不一樣狀態,而後渲染 UI,讓用戶界面和數據保持一致。React 裏,只需更新組件的 state,而後根據新的 state 從新渲染用戶界面 

var LikeButton = React.createClass({
    getInitialState: function() {
        /*
        * 設置狀態的初始值
        * */
        return {liked: false};
    },
    handleClick: function() {
        /*
        * 更改狀態
        * */
        this.setState({liked: !this.state.liked});
    },
    render: function() {
        var text = this.state.liked ? ‘喜歡’ : ‘不喜歡’;
        return (
        <p onClick={this.handleClick}>
        你 {text} 他. 點擊切換.
        </p>
        );
    }
});

ReactDOM.render(
<LikeButton />,
        document.getElementById(‘example’)
); 

  因爲 this.props 和 this.state 都用於描述組件的特性,可能會產生混淆。一個簡單的區分方法是,this.props 表示那些一旦定義,就再也不改變的特性,而 this.state 是會隨着用戶互動而產生變化的特性。

 

var Input = React.createClass({
    getInitialState: function() {
        return {value: ‘Hello!’};
    },
    handleChange: function(event) {
        this.setState({value: event.target.value});
    },
    render: function () {
        var value = this.state.value;
        return (
        <div>
        <input type=「text」 value={value} onChange={this.handleChange} />
        <p>{value}</p>
        </div>
        );
    }
});

ReactDOM.render(<Input/>, document.body);

 

組件 API

 

組件的7個方法:

  設置狀態:setState;

  替換狀態:replaceState;

  設置屬性setProps;

  替換屬性replaceProps;

  強制更新:forceUpdate;

  獲取DOM節點:getDOMNode;

  判斷組件掛載狀態:isMounted。

組件生命週期

初始化

getDefaultProps:設置默認性的值

getInitialState:設置初始的狀態

componentWillMount:(組件即將被裝載)

render(渲染)

componentDidMount:組件已經被裝載,只會在第一個組件被調用的時候出發

運行中

componentWillReceiveProps   在組件將要接收到屬性的時候,接收屬性前

shouldComponentUpdate    在接收到新的 props 或者 state,將要渲染以前調用。該方法在初始化渲染的時候不會調用

componentWillUpdate         render 觸發以前,更新

render              渲染

componentWillUnmount      在組件從 DOM 中移除的時候馬上被調用

銷燬

componentWillUnmount     在組件從 DOM 中移除的時候被馬上調用

 

var Hello = React.createClass({
    getInitialState: function () {
        return {
            opacity: 1.0
        };
    },

    componentDidMount: function () {
        this.timer = setInterval(function () {
            var opacity = this.state.opacity;
            opacity -= .05;
            if (opacity < 0.1){
                opacity = 1.0;
            }
            this.setState({
                opacity: opacity
            });
        }.bind(this), 100);
    },

    render: function () {
        return (
        <div style={{opacity: this.state.opacity}}>
        Hello {this.props.name}
        </div>
        );
    }
});

ReactDOM.render(
<Hello name=「world」/>,
        document.body
);

 

由於 React 組件樣式是一個對象第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象

 

Ajax

  上面代碼沒有使用 jQuery 完成 Ajax 請求,這是爲了便於說明。React 自己沒有任何依賴,徹底能夠不用jQuery,而使用其餘庫。

var Input = React.createClass({
    getInitialState: function () {
        return {users:[]}
    },
    componentDidMount:function(){
        var _this = this;
        $.get(「http://localhost:8080/users?act=get」,function (data){
            console.log(data);
            _this.setState({
                users:data
            });
        });
    },
    render: function () {
        var users = this.state.users;
        console.log(users);
        return <table>
        {
            users.map(function (user,key){
            return <tr key={key}><td>{user.firstName}</td><td>{user.lastName}</td></tr>
        })
        }
        </table>
    }
});
ReactDOM.render(<Input/>,document.getElementById(「test」));
相關文章
相關標籤/搜索