今天是鐵人賽的最後一天,剛好在昨天也介紹完了官方文件的 管理 State 篇章。後面還剩 逃脫出口 出口這個篇章沒介紹完,主要的內容會是對 React 以外的系統進行控制和同步,會用到 hooks: useRef
跟 useEffect
等。也是十分重要的篇章,所以之後應該也會花時間把它補完。
今天想介紹的是其實是官方文件放在比較前面的文章,但我覺得要先把一些 React 的用法先介紹完再來介紹這篇會比較好。標題是:用 React 的方式去思考 - Thinking in React
這個篇章會介紹如何用 React 的思考方式去設計一個頁面 UI,會從一個簡單的 mockup 開始,一步步用 React 完成 UI。
正常來說,我們開發的時候會拿到一份能獲得呈現資料的 API 跟設計師設計出來的畫面 mockup,mockup 就有點像是畫面的基本架構,還有沒把完整外觀呈現出來。我們會藉著 mockup 把畫面拆成可能的 React components。這次文章也是使用官方文件的範例。
通常我們在拆解的時候,會希望一個 component 專心做一件事,如果他會需要同時處理多個事物,那代表他可能可以把它拆成更細。Component 越細就越有機會被拿來重複利用。用文章的例子就會拆成像是:
會把 UI 分成:
FilterableProductTable
(灰色)是整個應用程式的容器。SearchBar
(藍色)用來接收使用者的輸入。ProductTable
(淡紫色)會根據使用者的輸入顯示並篩選清單。ProductCategoryRow
(綠色)用來顯示每個類別的標題。ProductRow
(黃色)顯示每筆產品資料的一列。拆解完後就可以把這些 component 分層:
FilterableProductTable
SearchBar
ProductTable
ProductCategoryRow
ProductRow
有了基本架構後,我們就可以試著用 React 把這些 component 先刻出一個靜態的版本。靜態的意思就是 UI 不會透過互動修改資料,只透過固定的資料呈現畫面。在這階段資料會只透過 props
在 component 之間傳輸,不會用到任何的 state,可以透過我們剛剛的分的層級來從上到下把 component 的位置刻出來,也可以從下到上,先把層級比較低的 component 先刻出來再去拼湊上層的 component。這個就比較看個人喜好。
把靜態的 UI 寫出來後,接下來就要把互動加進去,這就會需要用到之前學的 React state。在前面的篇章已經介紹滿多如何設計 state 的思考邏輯,這邊再整理一下:
而我們在範例會有需要使用到的資料有:
照著剛才的邏輯一個一個檢查:
props
傳遞,所以不會是 statefilter()
過後產生出來,所以不需要當作 state最後就會只留下紀錄使用者輸入文字的跟 checkbox 狀態的 state。
確定好會使用到哪些 state 後,就要思考要把 state 放在哪邊,會有以下步驟:
照著上面的步驟走:
1.
ProductTable
需要知道搜尋文字與 checkbox 狀態來篩選內容SearchBar
需要顯數輸入的搜尋文字與使用者勾選狀態FilterableProductTable
FilterableProductTable
在 FilterableProductTable
component 裡就可以寫上
function FilterableProductTable({ products }) {
const [filterText, setFilterText] = useState('');
const [inStockOnly, setInStockOnly] = useState(false);
return (
<div>
<SearchBar
filterText={filterText}
inStockOnly={inStockOnly}
/>
<ProductTable
products={products}
filterText={filterText}
inStockOnly={inStockOnly}
/>
</div>
)
}
找到 state 放入位置跟需要透過 props
傳遞的 component 後,我們還需要透過 handlers
來更新 state 不然畫面不會具有互動性,這時候就要使用剛剛在 FilterableProductTable
component 宣告的 state 們的 setter
向下傳入給 child components 使用。這樣才能透過傳下去的 setter
在 handler
裡觸發更新,反向的更新上層的 state。
<SearchBar
filterText={filterText}
inStockOnly={inStockOnly}
+ onFilterTextChange={setFilterText}
+ onInStockOnlyChange={setInStockOnly}
/>
這樣整個簡單的 UI 就可以順利地完成了。雖然還可以再多改善,像是可以再加入 CSS 讓畫面外觀更好看,或是把 ProductTable
裡的 component 做更細的處理,但主要概念還是上面介紹的步驟,可以讓我們在設計 React 應用程式上更為流暢。在開發的時候遇瓶頸也可以試著重新照著剛剛介紹的步驟再順過一次。
這次 30 天的鐵人賽就到這邊告一個段落,感謝大家耐心地看完。這次真的因爲時間很趕,所以各篇章篇幅都沒拿捏的恰當,還有好幾天是壓線過關的,其實中間有幾度差點要放棄,算是跌跌撞撞的寫完了。
前面提到還尚未介紹完的篇章,會持續補完,畢竟這次參賽的主要目的是自己的複習心得,要把全部篇章唸完才算完整。
最後再次感謝觀看的大家,如果有任何問題與建議都歡迎告訴我,之後的篇章見,晚安。