React 可以改變你對(duì)可見設(shè)計(jì)和應(yīng)用構(gòu)建的思考。當(dāng)你使用 React 構(gòu)建用戶界面時(shí),你首先會(huì)把它分解成一個(gè)個(gè) 組件,然后,你需要把這些組件連接在一起,使數(shù)據(jù)流經(jīng)它們。在本教程中,我們將引導(dǎo)你使用 React 構(gòu)建一個(gè)可搜索的產(chǎn)品數(shù)據(jù)表。
你的第一個(gè)組件
組件 是 React 的核心概念之一。它們是構(gòu)建用戶界面(UI)的基礎(chǔ),是你開始 React 之旅的最佳起點(diǎn)!
組件:UI 構(gòu)成要素
在 Web 當(dāng)中,HTML 允許我們使用其內(nèi)置的標(biāo)簽集(如 <h1> 和 <li>)創(chuàng)建豐富的結(jié)構(gòu)化文檔:
<article>
<h1>我的第一個(gè)組件</h1>
<ol>
<li>組件:UI 構(gòu)成要素</li>
<li>定義組件</li>
<li>使用組件</li>
</ol>
</article>
<article> 表示這篇文章,<h1> 表示文章的標(biāo)題,<ol> 以有序列表的形式表示文章的(縮寫的)目錄。每一個(gè)側(cè)邊欄、頭像、模態(tài)框、下拉框的背后是都是像這樣的(結(jié)合了用于樣式的 CSS 和用于交互的 JavaScript 的)標(biāo)簽——你在 Web 上看到的每一個(gè) UI 模塊。
React 允許你將標(biāo)簽、CSS 和 JavaScript 組合成自定義“組件”,即 應(yīng)用程序中可復(fù)用的 UI 元素。上文中表示目錄的代碼可以改寫成一個(gè)能夠在每個(gè)頁(yè)面中渲染的 <TableOfContents /> 組件。實(shí)際上,使用的依然是 <article>、<h1> 等相同的 HTML 標(biāo)簽。
定義組件
一直以來(lái),創(chuàng)建網(wǎng)頁(yè)時(shí),Web 開發(fā)人員會(huì)用標(biāo)簽描述內(nèi)容,然后通過(guò) JavaScript 來(lái)增加交互。這種在 Web 上添加交互的方式能產(chǎn)生出色的效果?,F(xiàn)在許多網(wǎng)站和全部應(yīng)用都需要交互。React 最為重視交互性且使用了相同的處理方式:React 組件是一段可以 使用標(biāo)簽進(jìn)行擴(kuò)展 的 JavaScript 函數(shù)。如下所示(你可以編輯下面的示例):
export default function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3Am.jpg"
alt="Katherine Johnson"
/>
)
}
以下是構(gòu)建組件的方法:
第一步:導(dǎo)出組件
export default 前綴是一種 JavaScript 標(biāo)準(zhǔn)語(yǔ)法(非 React 的特性)。它允許你導(dǎo)出一個(gè)文件中的主要函數(shù)以便你以后可以從其他文件引入它。
第二步:定義函數(shù)
使用 function Profile() { } 定義名為 Profile 的 JavaScript 函數(shù)。
React 組件是常規(guī)的 JavaScript 函數(shù),但 組件的名稱必須以大寫字母開頭,否則它們將無(wú)法運(yùn)行!
第三步:添加標(biāo)簽
這個(gè)組件返回一個(gè)帶有 src 和 alt 屬性的 <img /> 標(biāo)簽。<img /> 寫得像 HTML,但實(shí)際上是 JavaScript!這種語(yǔ)法被稱為 JSX,它允許你在 JavaScript 中嵌入標(biāo)簽。
返回語(yǔ)句可以全寫在一行上,如下面組件中所示:
return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;
但是,如果你的標(biāo)簽和 return 關(guān)鍵字不在同一行,則必須把它包裹在一對(duì)括號(hào)中,如下所示:
return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>+
);
沒(méi)有括號(hào)包裹的話,任何在
return下一行的代碼都 將被忽略!
使用組件
現(xiàn)在你已經(jīng)定義了 Profile 組件,你可以在其他組件中使用它。例如,你可以導(dǎo)出一個(gè)內(nèi)部使用了多個(gè) Profile 組件的 Gallery 組件:
function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3As.jpg"
alt="Katherine Johnson"
/>
);
}
export default function Gallery() {
return (
<section>
<h1>了不起的科學(xué)家</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
瀏覽器所看到的
注意下面兩者的區(qū)別:
<section> 是小寫的,所以 React 知道我們指的是 HTML 標(biāo)簽。
<Profile /> 以大寫 P 開頭,所以 React 知道我們想要使用名為 Profile 的組件。
然而 Profile 包含更多的 HTML:<img />。這是瀏覽器最后所看到的:
<section>
<h1>了不起的科學(xué)家</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>
嵌套和組織組件
組件是常規(guī)的 JavaScript 函數(shù),所以你可以將多個(gè)組件保存在同一份文件中。當(dāng)組件相對(duì)較小或彼此緊密相關(guān)時(shí),這是一種省事的處理方式。如果這個(gè)文件變得臃腫,你也可以隨時(shí)將 Profile 移動(dòng)到單獨(dú)的文件中。
因?yàn)?Profile 組件在 Gallery 組件中渲染——甚至好幾次!——我們可以認(rèn)為 Gallery 是一個(gè) 父組件,將每個(gè) Profile 渲染為一個(gè)“孩子”。這是 React 的神奇之處:你可以只定義組件一次,然后按需多處和多次使用。
組件可以渲染其他組件,但是 請(qǐng)不要嵌套他們的定義:
export default function Gallery() { // ?? 永遠(yuǎn)不要在組件中定義組件 function Profile() { // ... } // ... }上面這段代碼 非常慢,并且會(huì)導(dǎo)致 bug 產(chǎn)生。因此,你應(yīng)該在頂層定義每個(gè)組件:
當(dāng)子組件需要使用父組件的數(shù)據(jù)時(shí),你需要 通過(guò)props的形式進(jìn)行傳遞,而不是嵌套定義。