歡迎轉載(註明出處)或直接轉貼網址也ok,但是請不要直接把內容摳走貼在別的地方~

前言:

這是邊做邊學的心得啦!還是一樣依照本人上進心的餘額進行學習

這篇也是基礎到不行,只適合像我一樣的新手觀看

但因為一直在忙著鬼混,所以離上一篇居然隔了一個多月.....

參考資料當然還是官網

https://facebook.github.io/react/docs/tutorial.html

經過上一篇的開發環境建立之後

React 初學者筆記與教學 (一) - 新手村搞定開發環境

現在可以來先好好了解一下 React 這個 framework 這麼火熱的原因了

雖然這篇很基本,但首先還是要有目錄一下:

 

一、React 的發展與由來

二、Virtual DOM

三、元件 (Component)

1. 新增一個元件

2. 在元件中加入其他元件

3. 使用 props 、props.children 來做父子元件之間的傳接值

4. 透過外部物件陣列來給值

 

React 的發展與由來

以下開始拿學到的東西來屁

React 一開始是在 facebook 內部所使用的,直到 2013年5月才開源,想了解可以看下面連結

http://facebook.github.io/react/blog/2013/06/05/why-react.html

起因為 facebook 對市面上所有的 Javascript MVC Framework 都不滿意

(那時剛好是 AngularJS 1 火熱的時候)

果然有錢就是任性,facebook 因此決定自己寫一套,但 React 並不是另一套 MVC 的框架

他比較像是一個函式庫,它只專注於處理 MVC 裡面的 V 層

React 也不單純是一個使用樣板的函式庫,他把網頁分割成一個個的元件

然後透過等下要講的 Virtual DOM 機制,提供我們更好的 DOM操作方式,這就是 React 開始發展的精神

也因為他非常簡單入手,所以這幾年發展超級迅速,尤其 2015 React Native 發布之後

React Native

http://facebook.github.io/react-native/

React Native 的用途是讓我們可以用發展 Web App 的方式來開發 Native App 

讓我們可以用 React 跟 React Native 這個框架來開發 iOS 跟 Android 的 APP

但這個我應該很後面才會接觸到 (如果我的上進心還沒用完的話,就會來學一下)

這篇是React 的學習心得文,所以下面來認識一下 React 的核心機制 Virtual DOM

 

Virtual DOM

在以往我們要跟使用者在網頁上做一些互動,難免要做一些抓取或更新、操作 DOM 的動作

ex : 動態增加一個欄位、顯示 ajax 回來的訊息....等等

而這些動作在所有前端運作中可以說是最耗效能的,因為每次操作DOM的時候,頁面都必須要重繪一次

使用者才能看到最新的頁面效果,但你可能只是在頁面上加了一個 div 或是改變一下文字之類的...

如果只是針對少量的 DOM 節點去更新,其實效能並不會明顯差到哪去

但當有大量的 DOM 需要替換或更新的時候,這時效能的差距就會越來越明顯

因為瀏覽器必須要一直重繪頁面,尤其是那些複雜且多層的標籤

javascript 中有一個 DocumentFragment 的機制就是在想辦法處理這個問題的

DocumentFragment 運作的原理大概是這樣

在建立 Element 的時候不直接 append 到頁面上的 DOM 節點,因為每次 append 都會造成頁面重繪

而是先建一層假的 Element 叫 DocumentFragment,並將新建立的 Element 先加入 DocumentFragment

等完成所有動作之後再一次更新到頁面上

使用這樣的做法取決於原本的複雜程度,效能可以因此提升好幾倍

想繼續了解可以參考一下 MDN : 

https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment

 

屁了那麼多到底是要混版面還是要繼續學 React

其實兩者都是

如同我們手動使用 DocumentFragment 一樣,React 在與 DOM 之間的溝通也多了一層 Virtual DOM

Virtual DOM 不是真正的 DOM,是由 js 模擬出來的,但他也保留了 DOM 之間的層級關係和一些屬性

而Virtual DOM 也比原本要手動的 DocumentFragment 做的更為完美多了

一來他會自動地去幫你處理這些雜事,二來他會去計算上一次 Virtual DOM 跟這一次的差異

然後只把差異的部分處理後輸出到頁面的 DOM上,這種運算法叫做 DOM diff

剛剛一開始有講到,所有前端運算中成本最高的就是 DOM 的操作

所以有了 Virtual DOM 的幫忙之後,我們只需要在裡面進行邏輯運算

有關實際 DOM 的操作就交給 Virtual DOM 了

底下這篇文章是某個強人實作 Virtual DOM 的文章,對了解 React Virtual DOM 的運作方式會有點幫助

https://github.com/livoras/blog/issues/13

這篇討論也很精彩
https://www.zhihu.com/question/29504639


元件 (Component)

React 的另一個特點是他使用了元件的概念,將網頁上的區塊變成一個個的元件(或叫組件)

將網頁元素元件化之後,最後再把元件組裝成一個網頁 (有點像拼圖)

然後元件也跟 Virtual DOM 有點關係,每個元件都會有個 render 方法

而當元件的狀態(state)被改變了,React 就會呼叫元件的 render 方法去重繪整個元件的 UI

這個動作會透過 this.setState 方法來觸發 (這個放到下一篇再研究好了)

元件化的好處也有可重複使用與好維護的優點

雖然剛開始寫會有點不習慣,因為我到現在還有點難以適應啊!

 

1. 新增一個元件

接下來用官網範例來學習怎麼建立一個元件,底下都是用 JSX

下面是官網的範例

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


上面的例子,元件的名稱就叫做 CommentBox,而且很重要的是,第一個字一定要大寫!

不然會沒動作但也沒錯誤

React.createClass 就是建立元件的方法,裡面的 render方法回傳的就是網頁元件的內容

ReactDOM.render 則是將元件繪製到頁面指定的位置的方法 (之前的React.render已經被棄用)

所以上面這個範例意思就是

建立一個 CommentBox 元件,然後透過 ReactDOM.render 輸出到頁面上

執行後:

官網完整的範例在這邊 : https://facebook.github.io/react/docs/tutorial.html

第一次看到一個範例寫這麼長的,所以下面就直接擷取重點來了解一下

 

2. 在元件中加入其他元件

底下有三個元件 CommentList、CommentForm、CommentBox

建立元件的方法就是使用 createClass,元件名稱記得第一個字要大寫 (如下的 CommectList)

//CommentList
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
Hello, world! I am a CommentList.
</div>
);
}
});
//CommentForm
var CommentForm = React.createClass({
render: function() {
return (
<div className="commentForm">
Hello, world! I am a CommentForm.
</div>
);
}
});
//CommentBox
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<CommentList />
<CommentForm />
</div>
);
}
});
 
ReactDOM.render(
<CommentBox />,
document.getElementById('content')
);

然後在 CommentBox 元件裡面包含了 CommentList 跟 CommentForm 兩個元件

最後用 ReactDOM.render 輸出元件的內容

 

執行後:

所以使用元件就跟自訂HTML標籤一樣簡單 (但記得第一個字要大寫)

 

3. 使用 props 、props.children 來做父子元件之間的傳接值

如果你有多個元件,並且需要從父元件傳資料到子元件的話可以使用 props 

//CommentList
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
<Comment author="Pete Hunt">one comment</Comment>
<Comment author="Jordan Walke">another comment</Comment>
</div>
);
}
});
//Comment
var Comment = React.createClass({
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{this.props.children}
</div>
);
}
});
ReactDOM.render(
<CommentList />,
document.getElementById('content')
);

執行後:

元件的傳值看起來就跟使用 HTML 標籤的屬性一樣簡單

<Comment author="Pete Hunt">one comment</Comment>

像上面就透過自訂一個 author 屬性,來傳值到 Comment 元件

在元件內部則是用 this.props 來接單一屬性的值,ex : this.props.author

至於 this.props.children 則是用來抓取這個組件下面的所有子節點

通常抓到的值會是元件的陣列,但如果元件下面只有一個子項目的話,就不會使用陣列

有關 this.props.children 的說明可以看這邊

https://facebook.github.io/react/tips/children-props-type.html

官網也有 this.props.children 的操作方式,基本上就當作是多組物件陣列啦

https://facebook.github.io/react/docs/top-level-api.html#react.children

 

4. 透過外部物件陣列來給值

var data = [
{id: 1, author: "Pete Hunt", text: "This is one comment"},
{id: 2, author: "Jordan Walke", text: "This is *another* comment"}
];
var CommentList = React.createClass({
render: function() {
return (
<div className="commentList">
 
</div>
);
}
});
 
//CommentBox
var CommentBox = React.createClass({
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.props.data} />
</div>
);
}
});
ReactDOM.render(
<CommentBox data={data} />,
document.getElementById('content')
);

上面的例子從外面傳入 data 這個物件陣列到 CommentBox

然後在CommentBox 中用 this.props.data 來接,接到之後再傳給 CommentList

 

下一篇來研究一下 PropTypes 與 State

 

End

 

快快樂樂學 React  系列

=========================================

React 初學者筆記與教學 (一) - 新手村搞定開發環境

React 初學者筆記與教學 (二) - Virtual DOM、Component (元件) 的建立與傳值

React 初學者筆記與教學 (三) - State 的介紹與使用方式,讓你的元件可以跟使用者互動!

React 初學者筆記與教學 (四) - 使用 React.PropTypes 來驗證元件屬性

 

 

創作者介紹
創作者 小雕 的頭像
小雕

小雕雕的家

小雕 發表在 痞客邦 留言(2) 人氣()


留言列表 (2)

發表留言
  • mk
  • 請問.... :/
    第四個範例是不是有什麼部分有缺漏?
    我自己在codepen測試, 只有第四個run不出結果
  • hi 你好啊,

    sorry 我再改一下~
    因為 CommentBox 裡面使用了
    <CommentList data={this.props.data} />
    的關係,但是有沒有 CommentList 這個元件,所以就錯了

    你把這個加進去就會對了喔

    var CommentList = React.createClass({
    render: function() {
    return (
    <div className="commentList">

    </div>
    );
    }
    });

    小雕 於 2016/11/01 09:40 回覆

  • React初學者
  • 大大你好~父子元件的例子我不太清楚
    最後呈現在html的是<commentlist />
    然後它裡頭又包含了<comment/>這個元件
    到此還可以了解


    但輸出頁面顯示出來的文字都是在commentlist這個元件裡可以找到的
    導致我無法看懂元件間是如何透過語法互動
    感覺上是利用comment這個元件去把存在於author屬性的值讀出來?


    而父子元件跟「在元件中插入其他元件」的差別是⋯⋯?
    希望可以撥空說明一下謝謝><