上一篇文章「[React速成班]從TodoList範例學習React(1)-基本架構」中,我們學到了在React的世界中,一切都是由元件組成的,也在基於這樣概念中把TodoList基本上需要的元件框出來,接下來在這篇文章中我們將實作TodoItems的部分,順便學習React中元件與元件資料傳遞的方法。
除非我們做的都是純靜態的頁面,否則在前端處理資料一定會是一個重要的議題,在React中,對於資料的處理或傳遞有兩個主要的屬性:props和state。而props就是用來作為元件與元件之間傳遞資料的媒介。
關於props
props主要用來在元件與元件之前傳遞資料,例如我們希望在TodoList元件中,將要顯示的資料傳給TodoItems元件,那麼我們可以將原本TodoList元件中的render方法內容寫成這樣:
var TodoList = React.createClass({
render: function() {
var todoItems = [
{ id: 1, data: "Item 1" },
{ id: 2, data: "Item 2" }];
return (
<div className="todoList">
<h1>我是一個TodoList容器</h1>
<h2>我組合了TodoItems以及AddTodoForm兩個元件</h2>
<TodoItems items={todoItems}/>
<AddTodoForm />
</div>
);
}
});
在這邊我們可以看到render方法中我們宣告了一個todoItems變數,然後將它傳到TodoItems的items屬性裡面,而要將變數內容傳到React的元件屬性中,則必須用大誇號{}包起來。
而在TodoItems元件中,傳進來的todoItems就會放到this.props.items裡面,提供給元件內部使用,其中items就是要接收從外部傳來資料的參數屬性,因此我們的TodoItems元件程式碼就會變成這樣:
var TodoItems = React.createClass({
render: function() {
var displayItems = this.props.items.map(function(item) {
return (<li key={item.id}>{item.data}</li>);
});
return (
<div>
<ul>
{displayItems}
</ul>
</div>
);
}
});
在TodoItems的render方法中,我們透過this.props.items取得items參數的陣列內容,再利用map方法將它轉換為我們要顯示的HTML(JSX)語法,在這裡可以看到我們指定了key這個屬性,因為在React中要以陣列方式顯示的資料,都必須給定一個unique的key,當React將資料轉為顯示的View時會依據這些key給予每個html element不重複的id,如此一來當資料變更時,React就有足夠的依據知道哪些資料需要被變更而那些不需要。
現在TodoItems元件已經可以正常顯示要呈現的資料了,我們可以打開瀏覽器看到目前開發的成果:
可以看到我們的TodoItems元件正確的顯示我們所傳入的兩筆資料,此時若我們打開瀏覽器的開發人員工具(F12),就可以看到這兩筆資料都會依照我們給定的key來產生對應的id,這裡以Google Chrome的開發人員工具顯示為範例:
使用this.props.children取得節點裡的內容
到目前為止我們已經完成TodoItems的邏輯了,假設我們的<li>標籤有另外的邏輯需要處理,因此我們決定在分割出一個TodoItem(沒有s)的元件,並且將TodoItems改寫為:
var TodoItems = React.createClass({
render: function() {
var displayItems = this.props.items.map(function(item) {
// return (<li key={item.id}>{item.data}</li>);
return (<TodoItem key={item.id}>{item.data}</TodoItem>);
});
return (
<div>
<ul>
{displayItems}
</ul>
</div>
);
}
});
這樣的TodoItem元件該如何設計呢?很明顯我們可以在TodoItem中透過this.props.key來取得key屬性的資料,但{item.data}並沒有透過一個屬性名稱來傳遞,這時候我們就可以使用this.props.children來取得我們JSX跟節點內的內容,因此我們可以寫出一個TodoItem元件如下:
var TodoItem = React.createClass({
render: function(){
return (<li key={this.props.key}>{this.props.children}</li>);
}
})
再重新整理瀏覽器,一切顯示果然還是正常,太棒了!
單元回顧
在本篇文章中我們實際完成了TodoItems的顯示邏輯,也學到了在元件之前傳遞資料的方法,可以使用this.props取得外部傳過來的參數屬性資料,也可以透過this.props.children取得元件節點內部的資料內容。
本篇文章的程式碼片段可以到此Gist瀏覽。
在下篇文章我們再來完成另外一個AddTodoForm元件,順便學習另外一種處理資料的方法:state!