iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0
自我挑戰組

新手前端與真實世界的開發 feat.React 與他的夥伴系列 第 12

Day-12 專案演練 - React 拆元件的思路與操作(上)

  • 分享至 

  • xImage
  •  

Day-12 專案演練 - React 拆元件的思路與操作(上)

昨天玩了一下路由,今天在回來看 UI,我會將頁面上需要重複利用的樣式抽出來,在新建的 components 資料夾中保存,以前吃過樣式跟功能過度耦合的痛苦,逐漸養成了這個習慣。每個人思考元件的方式可能有所不同,我就分享一下我自己的思路是怎麼運轉的。

頁面與操作邏輯

操作邏輯跟頁面對不上是一件很可怕的事,如果使用者在操作到需要存檔的地方,卻沒有存檔的按鈕可以用,那會有多尷尬,用現實中的情境來對比,就是開心的用馬桶拉完屎之後才發現沒有沖水的桿子,差不多就是那種感覺...

也許,用水桶裝水來沖可以暫時緩解沒辦法沖水的問題,沒有存檔按鈕的使用者也可以用一通電話請,給資訊人員要輸入的資料跟請他幫忙存檔。

但不管怎樣,應該會先被使用者痛打一輪,一輪沒死透還要打兩輪。

如何使用 components 資料夾

為了示範,我先把一個小按鈕從 DefaultLayout 拆出來,就是 Menu 的那兩個按鈕。

  1. 新增 components 資料夾在 src 底下

  2. 新增 Button.tsx :

import React from "react";

const Button = ({ children, className }) => {
  return (
    <button className={`px-[8px] py-[2px] border rounded ${className}`}>
      {children}
    </button>
  );
};

export default Button;
  1. 將按鈕引入回去 DefaultLayout :
...
    <div className="flex justify-between items-center shadow px-[20px] py-[20px]">
            <h1 className="text-[30px] font-medium">
            <Link to="/">MyNote</Link>
            </h1>
            <div>
            <Button className="mr-[8px]">
                <Link to="/dashboard">Dashboard</Link>
            </Button>
            <Button className="mr-[8px]">
                <Link to="/todo">Todos</Link>
            </Button>
        </div>
    </div>
...

現在我們就有一個自己的 Button 元件,以後想要一個這種樣式的 Button,就直接引入就好囉!

typescript 報錯

因為輸入到的 Button.tsx 的屬性 children, className 隱含著any型別,因為我們並沒有給這些屬性設定型別,預設就是any,所以 typescript 會報錯。

先到根目錄的 tsconfig.json 將這個報錯關閉吧,只要加上"noImplicitAny": false就可以了。

{
  "compilerOptions": {
    "noImplicitAny": false,// 添加這一行
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

tip 對 typescript 不太了解的小夥伴,可以來看看這個中文教學,我剛入門的時候就是看這個。

如何使用 layouts 資料夾

通常我會跟路由來搭配使用,會使用到 react-router-dom 的 <Outlet>

在 Day-11 的示範當中有做過一次。

但其實還有另一個使用方式,就是在裡面放元素的容器,跟 component 相對的,就是放 container,例如 TodoPage 最外層的 ,再利用 children 來傳入子元件。

如何使用 pages 資料夾

以目前的專案來看,/todo 對上 pages 的 TodoPage.tsx,然後 /dashboard 對上 DashboardPage.tsx,目前的頁面數量少,架構簡單,跟路由很輕鬆地就能對上。

為了示範 pages 如何跟路由對上,我跟大家分享我目前手邊在做的專案,它的資料夾結構 :

pages,裡面每一個都是資料夾 :

├─case
├─client
├─dispatch
├─login
├─noMatch
├─renewal
└─todo

App.tsx

<Routes>
      <Route path="/" element={<DefaultLayout />}>
        <Route index element={<TodoPage />}></Route>
        <Route path="todo" element={<TodoPage />}>
        ...
        </Route>
        <Route path="case" element={<CasePage />}></Route>
        <Route path="case/list" element={<CasePage />}></Route>
        <Route path="case/repeat" element={<CaseRepeatPage />}></Route>
        <Route path="client" element={<ClientPage />}></Route>
        <Route path="dispatch" element={<DispatchPage />}></Route>

        <Route path="renewal" element={<RenewalPage />}>
        ...
        </Route>

    </Routes>

結語

拆元件的思路與操作可能會有二到三篇,在這個章節裡面我的流程會很 free,看起來就像我想到什麼我就寫成一段,寫一寫,又想到一個觀念,又增加新的一段,這很接近我實際上在做的時候會發生的事。

其實要把人做一件事情的流程(發散跳躍時快時慢,但最終會完成)做成一篇文章(一段接一段順序的敘述),有點難度,所以我的文章不太像教科書那樣會區分每個知識點,區分得很開。

看不太明白可以直接問我,如果有什麼想勘誤指教的,或者看不太懂得部分,都歡迎留言交流,謝謝大家。


上一篇
Day-11 專案演練 - 路由建置 react-router-dom
下一篇
Day-13 專案演練 - React 拆元件的思路與操作(中)
系列文
新手前端與真實世界的開發 feat.React 與他的夥伴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言