ReactJS入門學習一

龍恩0707發表於2015-08-20

ReactJS入門學習一

閱讀目錄

React是什麼?

    React僅僅是VIEW層,而我們經常看到Angular是一個完整的框架,而React不是,因此我們看到他們兩個的側重點不一樣,所以也不能比較的,React提供了模板語法及一些函式鉤子用於HTML的渲染,只用於View層。

React的優點?

      1. 虛擬DOM

  在DOM樹的狀態發生改變時,虛擬DOM機制會將前後DOM樹進行對比,如果兩個DOM樹有不一樣的地方,那麼React僅僅會對那些不一樣的區域來進行響應DOM修改,這也就是React的更高的效能是使用虛擬DOM來實現的。

      2. 資料流

  React實現了單向響應的資料流,從而減少了重複的程式碼,這也是為什麼比傳統資料繫結更簡單。

      瀏覽器對React的支援程度:IE9- 以下的瀏覽器是不支援React.

 下面我們來學習下React的基本使用方法吧!

  首先React擅長於元件化頁面,我們來看看使用React來如何渲染頁面的,如下程式碼:

   首先需要在頁面上引入React.js

<script src="./build/react.min.js"></script>

HTML程式碼結構如下:

<div id="content"></div>

JS程式碼如下:

<script>
        var CommentBox = React.createClass({
            displayName: 'CommentBox',
            render: function(){
                return (
                    React.createElement('div',{className:'commentBox'},"Hello,world!I am a CommentBox")
                );
            }
        });
        React.render(
            React.createElement(CommentBox,null),document.getElementById("content")
        );
</script>

在頁面上生成程式碼結構如下:

在IE9+ firefox chrome下生效;

我們下面來解釋下上面的程式碼的含義:

React.createClass(): 該方法來建立一個新的React元件;其中最重要的方法是render,該方法返回一顆React元件樹,這棵樹將會渲染成HTML;

上面的div標籤不是真實的DOM節點,他們是React div元件的例項,我們可以認為React是通過此來如何處理標記或者一些資料,React是安全的,它不生成HTML字串,所以預設阻止了xSS的攻擊;

React.render():該方法是 例項化根元件,啟動框架,它有第二個引數,含義是:注入標記到原始的DOM元素中; 

React 不依賴與Jquery,因此上面是通過 document.getElementById(“content”)來作為React.render()的第二個引數,當然我們也可以使用jqeury的方式來作為第二個引數呼叫,但是我們必須如下這樣:$(“#content”)[0], 而不是 $(“#content”);

React如何製作元件?

      如下我們有一個網站頁面:首頁分為如下幾塊,導航頁,側邊欄,還有內容區;假如我現在想導航頁,側邊欄和內容區都做成一個元件模組,因為有很多頁面需要公用的;如下page頁面結構圖:

那麼下面我們可以使用React.createClass()方法來建立一個react元件;如下程式碼:

導航頁程式碼如下:我們使用JSX來寫程式碼如下:(切記頁面需要引入)

<script src="./build/react.min.js"></script>

<script src="./build/JSXTransformer2.js"></script>

這句程式碼;這是目前測試的,方便點直接引入;

<script type="text/jsx">
        /* 導航模組程式碼 */
        var NavMode = React.createClass({
            render: function(){
                return (
                   <div className = "NavList">
                      Hello word! I am a Nav List
                   </div>
                );
            }
        });
        /* 側邊欄模組程式碼 */
        var SlideMode = React.createClass({
             render: function(){
                return (
                    <div className="slideMode">hello world! I am a slide</div>
                )
             }
        });
        /* 內容區模組程式碼 */
        var ContentMode = React.createClass({
            render: function(){
                return (
                    <div className="contentMode">Hello world! I am comtent</div>
                )
            }
        });
        /* 頁面div封裝 上面三個模組 */
        var page = React.createClass({
            render: function(){
                return (
                    <div className="homepage">
                        <h1>page首頁</h1>
                        <NavMode />
                        <SlideMode />
                        <ContentMode />
                    </div>
                )
            }
        });
        /* 初始化到content容器內 */
        React.render(
            React.createElement(page,null),document.getElementById("content")
        );
    </script>

頁面渲染完成後,檢視如下演示:

因此在頁面也可以看到預覽效果;如上是根據JSX的語法來混合HTML的標籤來建立我們的元件的,JSX編譯器會自動重寫HTML標籤為React.createElement(tagName)表示式。

理解元件屬性props

Props表示的是元件自身的屬性,是父層節點傳遞給子層節點的一些屬性或者資料,比如我的上面的程式碼,內容區,可能不同的模組有不同的內容,因此我們需要有相同的模板ContentMode 根據引數的傳遞不同而顯示不同的內容;程式碼如下:

/* 內容區模組程式碼 */
var ContentMode = React.createClass({
        render: function(){
            return (
                <div className="ContentMode">
<div class="contents">{this.props.contents}</div>
                    {this.props.children}
                </div>
            )
        }
});
/* 頁面div封裝 上面三個模組 */
var Page = React.createClass({
    render: function(){
        return (
            <div className="homepage">
                <ContentMode  contents ="longen">this is one comment</ContentMode >
                <ContentMode  contents ="longen2">this is two comment</ContentMode >
            </div>
            )
        }
});
/* 初始化到content容器內 */
React.render(
    React.createElement(Page,null),document.getElementById("content")
);

在頁面中顯示的DOM結構如下:

如上,我們從父節點Page傳遞給子節點ContentMode 的一些資料,從父節點傳遞到子節點的資料稱為 ”props”;

在JSX中通過javascript表示式放在大括號中(作為屬性或者子節點);我們訪問傳遞給元件的命名屬性作為 this.props的鍵,任何內嵌的元素作為this.props.children;

理解頁面中如何渲染資料的

比如發ajax請求等返回資料,現在我這邊是模擬靜態資料:如下返回資料:

var data = [{"name":'longen1',"age":'28'},{"name":'longen2',"age":30}];

現在我們要做的是 通過上面的data資料 分別渲染到content(內容區域去),第一步我們需要例項化根元件,呼叫React.render()方法;如下:

var data = [{"name":'longen1',"age":'28'},{"name":'longen2',"age":30}];

/* 初始化到content容器內 */
React.render(
    <ContentMode data={data} />, document.getElementById("content")
);
呼叫內容區域 ContentMode 模組,程式碼如下:
/* 內容區模組程式碼 */
var ContentMode = React.createClass({
    render: function(){
        return (
            <div className="ContentMode">
                <h1>內容渲染進來</h1>
                <Page data={this.props.data} />
            </div>
        )
    }
});

如上我們通過父層節點ContentMode 傳遞資料給子節點Page,Page模組通過this.props取到父節點傳來的資料,再呼叫Page模組,渲染資料,Page模組渲染資料如下:

var Page = React.createClass({
    render: function(){
        var ContentModes = this.props.data.map(function(content){
            return (
                <p className="pline" data-age={content.age}>{content.name}</p>
            )
        });
        return (
            <div className="homepage">{ContentModes}</div>
        )
    }
});

然後Page模組通過自身屬性 this.props取到值後 進行map遍歷,如下頁面演示效果:

HTML程式碼渲染成結構如下:

理解從伺服器端獲取資料及理解state的

現在我們來新建一個page.json來存放json資料,資料如下:

[{"name":"我是龍恩我來測試資料1","age":"28"},{"name":"我是塗根華我來測試資料2","age":"30"}]

現在讓我們來從伺服器端來獲取資料,我們先使用React.render()這個方法來初始化根元件;如下程式碼:

/* 初始化到content容器內 */

React.render(

     <ContentMode url="page.json" />, document.getElementById("content")

);

下面是所有的程式碼如下:

var Page = React.createClass({
    render: function(){
        var ContentModes = this.props.data.map(function(content){
            return (
                <p className="pline" data-age={content.age}>{content.name}</p>
            )
        });
        return (
            <div className="homepage">{ContentModes}</div>
        )
    }
});
/* 內容區模組程式碼 */
var ContentMode = React.createClass({
    getInitialState: function(){
        return {data:[]};
    },
    componentDidMount: function(){
        $.ajax({
            url: this.props.url,
            dataType:'json',
            success: function(data){
                this.setState({data:data});
            }.bind(this),
            error: function(xhr,status,err){
                console.log(this.props.url,status,err.toString());
            }.bind(this)
        });
    },
    render: function(){
        return (
            <div className="ContentMode">
                <h1>內容渲染進來</h1>
                <Page data={this.state.data} />
            </div>
        )
    }
});
/* 初始化到content容器內 */
React.render(
    <ContentMode url="page.json" />, document.getElementById("content")
);

到目前為止:我們的每一個元件都是根據自己的props渲染了自己一次,props是不可變的,他們是從父節點傳遞過來的資料,但是呢,如果我們需要從伺服器端更新資料的話,我們可以使用state來更新資料。this.state是元件私有的,我們可以通過this.setState() 來改變它,那麼元件會重新渲染下自己。

現在我們來分析下上面的程式碼:getInitialState()是在元件生命週期中僅執行一次,設定元件的初始化狀態。該方法是在React原始碼中做了封裝的。

componentDidMount() 是一個元件被渲染的時候React自動呼叫的方法,該方法也是React原始碼中封裝好了的,我們可以看到如上程式碼在呼叫getInitialState()方法時,給data定義了一個空陣列[]; 當呼叫componentDidMount() 方法時,通過發ajax請求(在此我們使用jquery來演示ajax),當有資料更新的時候,我們使用 this.setState({data:data}); 該方法,對資料data重寫賦值;從而改變原有的資料;然後使用新資料使UI自動更新;

在頁面上演示效果如下:

頁面HTML程式碼渲染結構如下:

我們也可以仿照新浪微博那樣,每隔幾秒中自動重新整理資料,這裡我們可以使用簡單的setInterval()來輪詢下,當然我們可以使用更好的方法 WebSockets技術

程式碼如下:

<script type="text/jsx">
    var Page = React.createClass({
        render: function(){
            var ContentModes = this.props.data.map(function(content){
                return (
                    <p className="pline" data-age={content.age}>{content.name}</p>
                )
            });
            return (
                <div className="homepage">{ContentModes}</div>
            )
        }
    });
    /* 內容區模組程式碼 */
    var ContentMode = React.createClass({
        getInitialState: function(){
            return {data:[]};
        },
        loadServer: function(){
            $.ajax({
                url: this.props.url,
                dataType:'json',
                success: function(data){
                    this.setState({data:data});
                }.bind(this),
                error: function(xhr,status,err){
                    console.log(this.props.url,status,err.toString());
                }.bind(this)
            });
        },
        componentDidMount: function(){
            this.loadServer();
            setInterval(this.loadServer,this.props.pollInterval);
        },
        render: function(){
            return (
                <div className="ContentMode">
                    <h1>內容渲染進來</h1>
                    <Page data={this.state.data} />
                </div>
            )
        }
    });
    /* 初始化到content容器內 */
    React.render(
        <ContentMode url="page.json" pollInterval={2000}/>, document.getElementById("content")
    );
</script>

如上程式碼,我們使它們每隔2秒鐘會發一次ajax請求,請求新資料回來;

好了 由於時間的關係 入門學習一 先介紹這裡,後面繼續學習!

相關文章