本文轉載自:眾成翻譯
譯者:iOSDevLog
連結:http://www.zcfy.cc/article/3821
原文:https://www.fullstackreact.com/30-days-of-react/day-5/
我們的應用程式中的硬編碼資料不是好主意。 今天,我們將把我們的元件設定為由資料驅動,訪問外部資料。
通過這一點,我們已經編寫了我們的第一個元件並將其設定為子/父關係。但是,我們還沒有將任何資料繫結到我們的React元件。雖然在React中寫一個網站是一個更愉快的體驗(在我們看來),我們還沒有利用React的力量來顯示任何動態資料。
今天我們來改一下。
資料驅動
回想一下,昨天我們構建了包含頭和活動列表的時間軸元件的開始:
我們將演示分解成元件,最終用靜態JSX模板構建了三個獨立的元件。每當我們改變網站的資料時,不得不更新我們元件的模板是不方便的。
而是讓我們給出要使用的元件資料進行顯示。我們從 <Header />
元件開始吧。現在,<Header />
元件只顯示元素的標題 Timeline
。這是一個很好的元素,它將是很好的能夠重用它在我們的頁面的其他部分,但標題是 Timeline
沒有意義的每一次使用。
讓我們告訴React,我們希望能夠將標題設定為別的東西。
介紹屬性
React允許我們以與HTML相同的語法向元件傳送資料,使用元件上的特性或 屬性
。這類似於將 src
屬性傳遞給影像標籤。我們可以考慮 <img />
標籤的屬性,因為prop我們正在設定呼叫的元件img。
我們可以訪問元件內的這些屬性 this.props
。讓我們看看在動作中使用 props
。
回想一下,我們將 <Header />
元件定義為:
class Header extends React.Component {
render() {
return (
<div className="header">
<div className="menuIcon">
<div className="dashTop"></div>
<div className="dashBottom"></div>
<div className="circle"></div>
</div>
<span className="title">
{this.props.title}
</span>
<input
type="text"
className="searchInput"
placeholder="Search ..." />
<div className="fa fa-search searchIcon"></div>
</div>
)
}
}
當我們使用該 <Header />
元件時,我們將它放在我們的 <App />
元件中:
<Header />
我們可以 title
作為一個屬性傳遞我們作為一個屬性,<Header />
通過更新元件的使用設定呼叫 title
某個字串的屬性,如下所示:
<Header title="Timeline" />
在我們的元件內部,我們可以 title
從課程中的 this.props
屬性訪問 Header
。而不是像 Timeline
模板一樣靜態設定標題,我們可以將其替換為傳入的屬性。
import React from `react`
class Header extends React.Component {
render() {
return (
<div className="header">
<div className="menuIcon">
<div className="dashTop"></div>
<div className="dashBottom"></div>
<div className="circle"></div>
</div>
<span className="title">
{this.props.title}
</span>
<input
type="text"
className="searchInput"
placeholder="Search ..." />
<div className="fa fa-search searchIcon"></div>
</div>
)
}
}
export default Header
現在我們的 <Header />
元件將顯示我們傳入的字串,title
當我們呼叫該元件時。例如,<Header />
像這樣呼叫我們的元件四次:
<Header title="Timeline" />
<Header title="Profile" />
<Header title="Settings" />
<Header title="Chat" />
結果四個 <Header />
元件載入完成後如下:
很漂亮,是嗎?現在我們可以複用 <Header />
元件, 使用一個動態 title
屬性。
我們可以傳遞不僅僅是元件中的字串。我們可以傳遞數字,字串,各種物件,甚至功能!我們將進一步討論如何定義這些不同的屬性,以便稍後構建元件api。
我們來看內容
元件,並用資料變數而不是而不是靜態設定內容和日期。就像我們可以使用HTML元件一樣,我們可以將多個 props
元件傳遞給元件。
回想一下,昨天我們定義了我們的 Content
容器,如下所示:
class Content extends React.Component {
render() {
return (
<div className="content">
<div className="line"></div>
{/* Timeline item */}
<div className="item">
<div className="avatar">
<img src="http://p0.qhimg.com/t01e9226cd16ce24fb4.jpg" />
Doug
</div>
<span className="time">
An hour ago
</span>
<p>Ate lunch</p>
<div className="commentCount">
2
</div>
</div>
{/* ... */}
</div>
)
}
}
和我們 title
一樣,我們來看看 props
我們的 Content
元件需求:
- 使用者的頭像圖片
- 活動的時間戳
- 活動項的文字
- 評論數量
假設我們有一個代表活動專案的JavaScript物件。我們將有一些欄位,如字串欄位(文字)和日期物件。我們可能會有一些巢狀的物件 user
和 comments
。例如:
{
timestamp: new Date().getTime(),
text: "Ate lunch",
user: {
id: 1,
name: `Nate`,
avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
},
comments: [
{ from: `Ari`, text: `Me too!` }
]
}
就像我們將一個字串標題傳遞給 <Header />
元件一樣,我們可以把這個 activity 物件傳遞給 Content
元件。我們轉換我們的元件來顯示它的模板內的這個活動的細節。
為了將動態變數的值傳遞給一個模板,我們必須使用模板語法在我們的模板中呈現。例如:
import React from `react`
class Content extends React.Component {
render() {
const {activity} = this.props; // ES6 destructuring
return (
<div className="content">
<div className="line"></div>
{/* Timeline item */}
<div className="item">
<div className="avatar">
<img
alt={activity.text}
src={activity.user.avatar} />
{activity.user.name}
</div>
<span className="time">
{activity.timestamp}
</span>
<p>{activity.text}</p>
<div className="commentCount">
{activity.comments.length}
</div>
</div>
</div>
)
}
}
export default Content
我們在我們的類定義中使用了一點ES6,在第一行定義就是這個render()
的解構函式。以下兩行在功能上相當:
// these lines do the same thing
const activity = this.props.activity;
const {activity} = this.props;
解構使我們能夠以更短,更緊湊的方式節省打字和定義變數。
然後,我們可以通過傳遞一個物件作為支援而不是硬編碼的字串來_使用_這個新內容。例如:
<Content activity={moment1} />
太棒了,現在我們有一個由一個物件驅動的活動項。但是,您可能已經注意到,我們將不得不使用不同的註釋實現這個多次。相反,我們可以將一組物件傳遞到元件中。
假設我們有一個包含多個活動專案的物件:
const activities = [
{
timestamp: new Date().getTime(),
text: "Ate lunch",
user: {
id: 1, name: `Nate`,
avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
},
comments: [{ from: `Ari`, text: `Me too!` }]
},
{
timestamp: new Date().getTime(),
text: "Woke up early for a beautiful run",
user: {
id: 2, name: `Ari`,
avatar: "http://www.croop.cl/UI/twitter/images/doug.jpg"
},
comments: [{ from: `Nate`, text: `I am so jealous` }]
},
]
我們可以 <Content />
通過傳遞多個活動來重新闡述我們的使用,而不僅僅是一個:
<Content activities={activities} />
但是,如果我們重新整理檢視什麼都不會出現!我們需要先更新我們的 Content
元件以接受多個活動。正如我們以前瞭解到的,JSX真的只是由瀏覽器執行的JavaScript。我們可以在JSX內容中執行JavaScript函式,因為它將像瀏覽器的JavaScript一樣執行。
我們將我們的活動專案 JSX 移動 map
到我們將針對每個專案執行的專案中。
import React from `react`
class Content extends React.Component {
render() {
const {activities} = this.props; // ES6 destructuring
return (
<div className="content">
<div className="line"></div>
{/* Timeline item */}
{activities.map((activity) => {
return (
<div className="item">
<div className="avatar">
<img
alt={activity.text}
src={activity.user.avatar} />
{activity.user.name}
</div>
<span className="time">
{activity.timestamp}
</span>
<p>{activity.text}</p>
<div className="commentCount">
{activity.comments.length}
</div>
</div>
);
})}
</div>
)
}
}
export default Content
現在我們可以將任何數量的活動傳遞給我們的陣列,Content
元件將處理它,但是如果我們現在離開元件,那麼我們將有一個相對複雜的元件處理,包含和顯示活動列表。像這樣離開真的不是React的方式。
活動項
這裡寫一個元件包含顯示單個活動項然後再建立一個複雜的 Content
元件是有意義的,我們可以移動責任。這也將使測試更容易,新增功能等
讓我們更新我們的 Content
元件以顯示元件列表 ActivityItem
(我們將在下面建立)。
import React from `react`
import ActivityItem from `./ActivityItem`;
class Content extends React.Component {
render() {
const {activities} = this.props; // ES6 destructuring
return (
<div className="content">
<div className="line"></div>
{/* Timeline item */}
{activities.map((activity) => (
<ActivityItem
activity={activity} />
))}
</div>
)
}
}
export default Content
這不僅僅是簡單易懂,而且使得這兩個元件的測試更容易。
使用我們新鮮的 Content
元件,讓我們建立 ActivityItem
元件。由於我們已經為此建立了檢視 ActivityItem
,所以我們需要做的就是將它從我們 Content
元件的模板複製為自己的模組。
import React from `react`
class ActivityItem extends React.Component {
render() {
const {activity} = this.props; // ES6 destructuring
return (
<div className="item">
<div className="avatar">
<img
alt={activity.text}
src={activity.user.avatar} />
{activity.user.name}
</div>
<span className="time">
{activity.timestamp}
</span>
<p>{activity.text}</p>
<div className="commentCount">
{activity.comments.length}
</div>
</div>
)
}
}
export default ActivityItem
本週,我們使用React props
概念更新了由資料驅動的元件。在下一節中,我們將介紹有狀態的元件。