2-6 建立第一個 React 元件

在 React 中,除了把 JSX 當成一個變數 JavaScript 變數直接傳遞之外,更常見的是把 JSX 的內容包成一個 React 元件,至於要怎麼把 JSX 包成 React 元件呢?

在本單元中將會說明如何使用函式來建立 React 元件,完成後的畫面會像這樣子:

Imgur

建立 React Component#

關於這點,其實你早就會了,就是建立一個函式把 JSX 的內容回傳出來而已。像這樣,我們就建立了一個名為 Counter 的 React 元件:

// 建立一個名為 Counter 的 React 元件
const Counter = () => {
return (
<div className="container">
<div className="chevron chevron-up" />
<div className="number">256</div>
<div className="chevron chevron-down" />
</div>
);
};

React 是不是很簡單啊(誤)。另外在箭頭函式(arrow function)中,當該函式只是單純回傳某一值時,可以把要回傳的內容直接放到 => 後面而不用額外再寫 return,因此會精簡成這樣:

// 建立一個名為 Counter 的 React 元件
const Counter = () => (
<div className="container">
<div className="chevron chevron-up" />
<div className="number">256</div>
<div className="chevron chevron-down" />
</div>
);
info

💡 這裡使用函式所建立出的 React 元件,稱作 Function Component,而稍後單元中談到的 React Hooks 也只能在 Function Component 中使用。在還沒有 React Hooks 以前,則常會以 class 的方式來建立元件,稱作 Class Component。

使用 React Component#

原本我們是在 ReactDOM.render() 中的第一個參數放入 JSX,現在只需把剛剛建立好的 React 元件當成一個 HTML 標籤(<Counter />)放進去就可以了,像是這樣:

const Counter = () => (
<div className="container">
<div className="chevron chevron-up" />
<div className="number">256</div>
<div className="chevron chevron-down" />
</div>
);
// 使用 <Counter /> 來帶入 React 元件
ReactDOM.render(<Counter />, document.getElementById('root'));

你會發現這麼做和原本建立變數後帶進去的寫法差異不大:

imgur

為什麼使用元件#

你可能會好奇把原本的 HTML 包成一個 React 元件有什麼好處呢?假設現在碰到一個情況,是需要一個頁面中同時需要很多個計數器的話,像是下圖這樣,可以怎麼做呢?

Imgur

我們當然可以複製同樣的 HTML 到程式碼中,但因為原本的 JavaScript 都是透過 querySelector 來選到 DOM 元素後再對不同的元素去監聽事件和改變數值,因此當我們直接複製三次時,因為 querySelector 會選到重複的元素,所以我們必須要再去修改程式碼才能讓這三個計數器都擁有正常的功能。簡單來說,用原生 JavaScript 來寫絕對做得到,但就是比較麻煩。

而元件的好處在於讓開發者可以輕鬆的重複使用這些元件,當我們需要三個計數器時,只需要使用三次 <Counter /> 就可以了,像是這樣:

const Counter = () => (
<div
className="container"
style={{
margin: '0 30px',
}}
>
<div className="chevron chevron-up" />
<div className="number">256</div>
<div className="chevron chevron-down" />
</div>
);
// 使用 <Counter /> 來帶入 React 元件
ReactDOM.render(
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Counter />
<Counter />
<Counter />
</div>,
document.getElementById('root')
);

透過元件除了可以幫助開發者根據每個元素的功能去做切割分類以提高維護性外,很重要的還包括元件讓開發者可以建立可被重複使用的 HTML 元素、樣式或操作邏輯,當未來需要修改的時候,你不需要在到每隻檔案去做修改,只需要修改這個被共用到的元件即可。

React 元件與 HTML 元素的命名規則與慣例#

在 React 中對於元件和 HTML 屬性、CSS 樣式等等有一些命名上的「慣例」,當沒有照著這些慣例來命名時,會出現錯誤的提示,多半時候你只需要知道大致上的規則,當看到錯誤提示時再依據錯誤的提示進行修改就可以了。

React 的「元件名稱」會以大寫駝峰的方式來命名,也就是首字母大寫,例如, Counter,若該名稱由多個單字組成,則把每一單字的第一個字大寫,例如,AdminHeaderPaymentButton。如果沒這麼做的話,React 會把它當作一般的 HTML 元素處理,並跳出錯誤提示。

例如,如果我們把 <Counter /> 改成小寫開頭的 <counter />,瀏覽器的 console 將會跳出錯誤訊息:

Warning: The tag <counter> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

其他像是 HTML 中的屬性、CSS 樣式屬性或一般的函式來說,則會遵行 JavaScript 以小寫駝峰來命名變數的慣例,例如 classNamemaxLengthbackgroundColor 等等。

<input type="text" maxlength="10" /> 為例,在 React 的 JSX 中需要把 maxlength 改成 maxLength,不然一樣會拋出錯誤,舉例來說:

<!--
- 在 JSX 中屬性如果由多個單字組成,需要使用小寫駝峰命名,否則會有錯誤訊息
- Warning: Invalid DOM property `maxlength`. Did you mean `maxLength`?
-->
<input type="text" maxlength="10" />
<!-- 正確寫法 -->
<input type="text" maxlength="10" />

使用慣例的好處是當自己或他人看到程式碼時,可以很快從變數的命名了解它可能的類型,例如,當看到以大寫駝峰方式命名的變數時,可以馬上知道這是個 React 元件而非一般的函式。

換你了:建立出第一個 React Component 吧#

在這個單元中我們說明了如何建立 React 元件、使用元件的好處、以及元件的命名規則。現在要換你試著把原本的 JSX 改寫成 React 元件,在後面的單元中將會開始說明如何在 React Component 上綁定事件,以做到增減數字的功能。若對於這個單元的程式碼在實作上有什麼問題,都可以到下方的連結查看原始碼:

https://codepen.io/PJCHENder/pen/WNrxZxQ

Imgur