3-5 React 元件的拆分
本單元對應的專案分支為:split-components
。
先前,我們在整個頁面中都只使用了一個 React 元件,並把所有的 HTML 結構包在這個元件中
在這個元件中包含所有的 HTML 結構,但是當專案一大起來之後,一個頁面中若包含所有的 HTML 結構、邏輯判斷等等,將會變得難以管理,你可以想像一隻檔案打開來後有好幾萬行,要如何找到想要修改的元素呢?
因此在 React 中,元件除了能方便開發者重複使用外,還有一點是讓開發者去管理各個「功能獨立」的元素,並且把每個元件都拆分成獨立的 JS 檔案後,管理上就會方便許多了。
在這個單元中最後呈現的畫面不會有太大的變化,但元件和檔案的拆分則會有明顯的不同。
讀者們可以先留意一下,這裡我們會先把 <div className="unit-control">...</div>
和 <div className="card-footer">...</div>
的部分先進行元件的拆分;對於中間的 <div className="converter">...</div>
區塊,因為會需要更多資料傳遞的觀念,為了避免一次吸收太多的資訊而難以消化,因此會在後面的單元再來拆分這個部分。
#
拆出 UnitControl 元件React 元件的拆分非常簡單,其實你早就會了。舉例來說,現在想要把 <div className="unit-control">...</div>
的這個區塊拆成一個獨立的元件:
只需要透過函式定義一個新的 React 元件,名稱就取為 UnitControl
,要留意的是 React 元件的命名是使用大寫駝峰,因此首字需要大寫,同時因為這個元件單純只是要回傳 JSX 而沒有要做其他處理,所以可以在箭頭函式的 =>
後直接回傳 JSX 即可,像這樣:
這樣就完成了一個名為 <UnitControl />
的 React 元件,只需要在你想要使用它的地方帶入即可,像是下圖這樣:
#
建立 CardFooter 元件除了 <UnitControl />
可以拆分成獨立的元件外,我們也進一步把 <div class="card-footer">...</div>
的部分拆成一個獨立的元件,像這是這樣:
接著同樣在原本的位置把這個元件套用進去:
💡 小提醒:這裡讀者可能會有些困惑, CardFooter 才一行而已為什麼要拆成一個元件?這主要是因為在後面的單元中將會對它做更多的變化,因此這裡實作時先把它進行拆分。
#
檔案拆分現在你會發現在同一支 app.js
中就包含了三個 React 元件,目前因為程式碼還不多,所以不會感到太過複雜,但未來如果內容變多或需要在元件中進行邏輯運算時,在一隻檔案中包含多個元件就不會是太好的做法。好在透過 ES Module 系統,可以把元件拆分成不同的檔案。
#
新增 components 資料夾現在我們先在 src
中新增 components
資料夾,並分別在裡面新增 UnitControl.js
和 CardFooter.js
這兩隻檔案,檔案目錄會長像這樣:
#
建立 UnitControl 檔案接著在 src/components/UnitControl.js
中,先匯入 React 套件,把原本寫在 App.js
中的 UnitControl
元件剪下放進來,然後用 export default
加以匯出:
caution
小提醒:只要有用到 JSX 的檔案,都記得要在最上方匯入 React 套件,檔案才能被正確解析。
#
建立 CardFooter同樣的,把原本寫在 App.js
中的 CardFooter
元件剪下放進來,然後用 export default
加以匯出:
#
在 App.js 中匯入 Component最後,回到 App.js
中,只需要把剛剛 export 的元件匯入(import
)即可直接使用,程式碼幾乎不用動:
#
換你了:試著拆分 React 元件吧現在要請你試著把 UnitControl
和 CardFooter
這兩個元件拆分出來,分別放在 components
資料夾中的 UnitControl.js
和 CardFooter.js
。拆分完之後,一樣記得透過 npm start
來把專案啟動起來,這時候的畫面應該一樣可以正常顯示,並且沒有任何不同:
- 在
./src/components/UnitControl.js
中建立 UnitControl 元件 - 在
./src/components/CardFooter.js
中建立 CardFooter 元件 - 在
./App.js
中匯入 UnitControl 和 CardFooter -
npm start
確認專案能正確啟動
在這個單元中,對於中間的 <div className="converter">...</div>
區塊還沒有進行元件的拆份,這是因為這個區塊有綁定事件在內,會需要更多資料傳遞的觀念,為了避免一次吸收太多的資訊而難以消化,因此會在後面的單元再來拆分這個部分。
在下一個單元中我們要先讓 CardFooter 的文字和顏色能根據網速而有不同的呈現方式。本單元相關之網頁連結、完整程式碼與程式碼變更部分可於 split-components
分支檢視:https://github.com/pjchender/learn-react-from-hooks-internet-speed-converter/tree/split-components: