客戶說要有按鈕,就有了按鈕
用 VS Code 開啟我們昨天建立的 day-1-hello-react,
首先來觀察專案結構,應該會長這樣。
可以發現有幾個是灰字的資料夾或是檔案,先跳過不看,主要觀察這些內容
day-1-hello-react/
├── app/
│ ├── root.tsx
│ ├── routes.ts
│ ├── routes/
│ │ └── home.tsx
│ ├── welcome/
│ │ └── welcome.tsx
│ └── app.css
├── public/
│ └── favicon.ico
├── package.json
├── package-lock.json
├── react-router.config.ts
├── vite.config.ts
├── tsconfig.json
└── Dockerfile
首先注意到整份專案大部分用 TypeScript。
副檔名:
.ts是 TypeScript 程式碼,.tsx則可以在 TypeScript 裡使用 JSX
關於 JSX
這是因為 create-react-router 預設是採用 TypeScript 建立,接著來看 day-1-hello-react 每個檔案負責的東西吧。
| 檔案或資料夾 | 在專案裡負責 |
|---|---|
app/ |
放應用程式的相關 code ,今天主要在這裡面建立元件 |
app/root.tsx |
根路由(Root Route);會在這裡設定網頁外層結構與子路由顯示位置 |
app/routes.ts |
設定網址要對應到哪個路由檔案,預設是 home |
app/routes/home.tsx |
首頁,裡面使用到 Welcome 元件 |
app/welcome/welcome.tsx |
歡迎畫面的元件,昨天修改文字的地方 |
app/app.css |
全域樣式;這裡引入了 Tailwind CSS |
public/ |
放靜態檔案,例如網站小圖示 |
package.json |
記錄專案使用的套件與可執行的指令 |
其他檔案:
package-lock.json記錄套件解析後的版本vite.config.tsVite 的開發與建置設定。react-router.config.tsReact Router 框架設定。tsconfig.jsonTypeScript 設定。Dockerfile與容器部署有關
這裡要注意的是,不同的模板會產生不同的專案結構。create-react-router 會通過 React Router 框架建立 React 專案,
所以資料夾裡除了寫畫面的程式碼,也已經有路由、開發工具和相關設定。
想成一套安排好的開發方式:一些常見工作已經有規則和工具,例如在哪裡設定路由、怎麼啟動開發環境。照著這些規則放入自己的程式碼與修改配置檔,利用框架把各部分接起來。
對照這份專案,來認識三個名字:
| 名稱 | 角色 | 在專案中的檔案/名稱 |
|---|---|---|
| React | 建立 UI 的函式庫 | Home、Welcome 都是 React 元件 |
| React Router | 提供路由功能;包含框架模式,整合路由、建置等功能 | routes.ts 設定首頁,root.tsx 提供根路由 |
| Vite | 提供開發伺服器與正式建置工具 | vite.config.ts 載入 React Router 與 Tailwind CSS 的外掛 |
這些工具在專案裡一起工作。React 的官方文件也將 React Router 列為建立 React 應用程式的框架選項;框架模式與 Vite 的整合可參考 React Router 官方說明,Vite 的用途則見官方指南。
以防我失智忘了這些東西,順便記一下
Node.js:執行這些開發工具的環境
npm:負責套件安裝,也可以執行package.json裡設定好的指令
路由 (routing) 就是根據網址,決定顯示哪個頁面;Router 是處理這件事的工具。
例如一個簡單的網站可能有這些:
| 網址路徑 | 對應畫面 |
|---|---|
/ |
首頁 |
/about |
關於我們 |
/products |
商品列表 |
在目前的專案 day-1-hello-react 中只有首頁
| 網址路徑 | 對應畫面 |
|---|---|
/ |
首頁 |
延續上面的路由概念來看 React Router 就不會搞混了。
因為 React 本身沒有內建路由,Vite 也沒有提供頁面的路由設定,這個模板選擇用 React Router 處理路由。
此時 React Router 可以搭配其他建置工具使用;現在所使用的做法是框架模式整合了 Vite,所以專案裡才會同時看到它們。如果只使用 Vite 的基本 React 模板建立專案,預設並不會包含 React Router。模式差異可以參考 React Router 官方說明。
在 React 官方也將路由列為需要另外處理的應用程式功能。React 官方文件
承上題 (我考試最討厭這句)
Vite 是前端開發與建置工具
這裡分兩段理解
寫程式時:在自己的電腦預覽畫面。
在自己的電腦上執行一個程式,接收瀏覽器的請求,提供開發中的網頁與所需資源。例如 http://localhost:5173/,其中 localhost 指的就是自己的電腦。伺服器保持執行時,就能透過這個網址查看目前的成果。
.tsx 包含 TypeScript 和 JSX,Vite 會配合外掛將這些程式碼轉換成可執行的 JavaScript,讓瀏覽器能顯示畫面。它也會追蹤檔案變動:存檔後,通常能快速更新受影響的部分,不必每改一行就重新啟動整個專案。這背後用到了熱模組替換 (HMR) 等更新機制;某些變更仍可能讓頁面重新載入。昨天改完 Hello-React!! 就看到結果,正是這套開發流程在幫忙。Vite 官方指南
準備部署時:把程式碼轉換成正式運作的版本。
建置 (build) 會轉換、打包程式碼,並處理 CSS、圖片等資源,產生供部署使用的檔案。建置完成表示檔案準備好了,之後還要部署到適合的主機環境,網站才會對外提供服務。
接著讓我們進程式檔案說明。
前面都提到了 Vite,那就延續介紹![]()
這個模板中的 package.json 裡已經設定好指令:
| 指令 | 實際執行 | 用途 |
|---|---|---|
npm run dev |
react-router dev |
透過 React Router 整合 Vite,啟動開發環境 |
npm run build |
react-router build |
透過 React Router 整合 Vite,產生正式建置檔案 |
打開 vite.config.ts,會看到 plugins: [tailwindcss(), reactRouter()],這就是把樣式工具與 React Router 接進 Vite 的設定。
開啟 app/routes.ts 會看到:
import { type RouteConfig, index } from "@react-router/dev/routes";
export default [index("routes/home.tsx")] satisfies RouteConfig;
index("routes/home.tsx") 這段。index 用來指定父路由網址下的預設頁面,
也就是在目前的設定裡,/ 的首頁內容會交給 app/routes/home.tsx。
主要關注這一段:
export default function App() {
return <Outlet />;
}
Outlet 是從 react-router 匯入的元件,「顯示符合目前網址的子路由內容的位置」。在首頁裡會放入 home.tsx 匯出的 Home 元件。
同一個檔案裡的 Layout 還安排了 <html>、<head>、<body> 等外層結構,作為網頁的主框架。
Layout 裡的 {children} 是放入內容的位置。在這份範例正常顯示首頁時,React Router 讓 App 的內容出現在這裡;App 裡的 再顯示首頁的 Home 元件。
開啟 app/routes/home.tsx:
import { Welcome } from "../welcome/welcome";
export default function Home() {
return <Welcome />;
}
第一行從另一個檔案匯入 Welcome,Home 函式再把 <Welcome /> 放進畫面。
路徑裡的 .. 表示往上一層:從 routes 回到 app,再進入 welcome 資料夾。
開啟 app/welcome/welcome.tsx,搜尋昨天修改的 Hello-React!!。
可以在 welcome.tsx 看到文字放在內層的 <p> ...</p> 裡面,並且 function Welcome() 會將底下的類 HTML 內容 return。
好了,現在專案內檔案之間的關係,整理完成就會長這樣:
routes.ts:把 / 對應到 routes/home.tsx
root.tsx:外層結構與 App
└── Outlet:顯示首頁內容
└── Home
└── Welcome
└── <p>Hello-React!!</p>
元件 (component) 能拿來組合畫面的實際內容。它可以是一個小標題、一張介紹卡片,也可以是一整頁。
所以其實從剛剛提到檔案之間的關係就可以發現,在 welcome.tsx 中,function Welcome()就是一個元件。
一個最基本的函式元件,可以這樣寫:
function LearningNote() {
return <p>今天開始認識 React 元件。</p>;
}
自訂元件名稱要大寫開頭,當元件要回傳多個並排的 JSX 元素時,可以用 <> ... </>(Fragment)包起來。
像 <p> 這種小寫標籤,則是內建的 HTML 元素。元件可以放進其他元件的 JSX 裡組合使用,定義函式時則放在檔案最外層。這些基本規則可參考 React 的第一個元件教學。
此外,元件和檔案不是一對一的關係,同一個檔案可以定義多個元件喔。
先確認昨天的專案還能正常跑。在 VS Code 終端機切到 day-1-hello-react,執行:
npm run dev
確認還看得到 Hello-React!!後,我們來修改與建立元件。
開啟 app/welcome/welcome.tsx,在兩行圖片的 import 下方、export function Welcome() 上方,加入:
function LearningNote() {
return <p>今天開始認識 React 元件。</p>;
}
注意是放在 Welcome 函式外面。
接著在Hello-React!! 的</p>後面一行插入:
<LearningNote />
存檔後會在 Hello-React!! 下方,多出「今天開始認識 React 元件。」這行。
這樣我們就可以收工,啊不是,客戶說要放按鈕。
首先,加上函式元件
function MyButton() {
return <button
className="cursor-pointer bg-blue-500 px-3 py-1 text-white"
type="button"
>
按鈕來了
</button>;
}
className 裡使用的是專案已經設定好的 Tailwind CSS 樣式:bg-blue-500 加上藍底、text-white 設定白字,px-3 py-1 留出內距,cursor-pointer 讓游標變成手指。
最後把<MyButton/>一樣加到 <LearningNote/> 後面,再看一次畫面。
太好了,客戶的要求做完了(撒花)
你說什麼?客戶想要整個畫面都換新的?![]()