iT邦幫忙

2026 iThome 鐵人賽

DAY 24
0
佛心分享-IT 人職涯歷練

從 UI/UX 麻瓜到工程魔法師|從讀懂程式開始系列 第 24 篇

Day 24|不要急著重做 Component,也許你只是還沒看懂它原本提供的參數

  • 分享至 

  • xImage
  •  

做前端做到一段時間後,很容易遇到這種情況:

原本 Component
↓
看起來不符合需求
↓
開始想辦法繞
↓
越改越複雜
↓
最後才發現:

其實原本就有一個參數可以做到

這種時候最想做的通常不是 Debug。

而是:

去牆角安靜三分鐘。

我自己以前很容易有一個習慣:

看到元件不符合需求,就先想「我要怎麼改掉它」。

但後來慢慢發現,很多時候真正該先問的是:

這個元件原本到底支援什麼?


一個很常見的情境:數字欄位看起來不符合需求

假設專案裡原本已經有一個共用的數字輸入元件。

概念上像:

<AmountInput />

但某次需求希望:

可以顯示特定格式
可以保留原本數字行為
又要符合新的顯示需求

第一眼看:

這個 Component 好像做不到。

所以很容易開始:

換成普通 Input
↓
自己處理 value
↓
自己 parse
↓
自己 format
↓
自己處理空值
↓
自己處理小數
↓
自己處理表單

結果原本只是一個欄位,

開始長出一大堆額外邏輯。


問題是:普通 Input 不一定等於原本 Component

原本數字元件可能已經偷偷幫我們處理:

number type
format
parser
precision
min / max
Form integration
validation
空值

如果直接換成:

<Input />

畫面看起來可能暫時一樣。

但資料層其實已經變了。

例如原本:

100

是:

Number

換成普通 Input 後:

"100"

可能變成:

String

這件事如果沒有注意,

後面送 API 時就可能再出現型別問題。


所以「能顯示」不代表「行為一樣」

這點我後來很有感。

UI Component 不是只有:

長什麼樣子

它還可能負責:

輸入型別
資料格式
驗證
Form 行為
事件

所以把:

<InputNumber />

改成:

<Input />

並不只是換 UI。

有可能連資料 contract 都一起改了。


這時候應該先看 Component API

如果是:

Ant Design
Ant Design Pro
公司共用元件

我現在會先做一件事:

找它支援哪些 Props

例如:

<Component
  formatter={...}
  parser={...}
  precision={...}
  fieldProps={...}
/>

也可能是公司自己包裝的:

<AmountField
  showSymbol={false}
/>

重點不在參數名稱。

而是先確認:

原本 Component 有沒有已經提供這個能力?


以前我會從「我要怎麼做到」開始

例如:

我要把這個數字欄位改成某種樣子。

腦袋會直接進:

要不要換 Input?
要不要自己寫 formatter?
要不要另外存 State?

現在我會先換一個順序:

① 現在使用什麼 Component?

② 它從哪裡 import?

③ 是套件的還是專案共用的?

④ 它有哪些 Props?

⑤ 專案其他地方有沒有類似用法?

⑥ 現有能力真的做不到,再考慮重做。

這個順序其實省很多時間。


第一件事:先看 Import

例如:

import AmountInput from "@/components/AmountInput"

這跟:

import { InputNumber } from "antd"

意義差很多。

第一種:

專案自己包裝的 Component

第二種:

第三方套件 Component

如果是公司自己包的:

AmountInput

我會先進去看:

它到底包了什麼?

有時候會發現:

return (
  <InputNumber
    formatter={...}
    parser={...}
    {...props}
  />
)

這就代表:

它本身可能已經允許外面傳更多設定進來。


第二件事:搜尋專案裡其他人怎麼用

這個方法對我非常有用。

假設現在看到:

<AmountInput />

不知道某個需求怎麼做,

可以直接搜尋:

AmountInput

看看其他頁面是不是有人寫:

<AmountInput
  someProp={...}
/>

有時候文件還沒看到答案,

專案裡其實已經有人做過。

這種 Existing Pattern 非常值得先參考。

因為它除了告訴我:

這個 Component 能不能做到

還告訴我:

這個專案習慣怎麼做到。


「看別人怎麼寫」不是抄答案

以前我可能會覺得:

工程師是不是應該自己想出來?

但實際專案裡,

保持一致性本身就是很重要的事情。

如果:

同一個需求

專案其他地方已經有:

既有 Component
既有 Pattern
既有 Utility

重新自己發明一套,

反而會增加:

維護成本
行為差異
重複邏輯

所以搜尋 Existing Pattern 不是偷懶。

而是在問:

這個 Codebase 已經怎麼解這件事?


第三件事:看文件,但不要只看 Component 名字

假設用了:

<InputNumber />

不要只看:

InputNumber 是數字輸入框

真正有用的是去看:

Props

例如:

formatter
parser
precision
stringMode
controls
min
max

因為很多需求其實不是:

Component 做不到。

而是:

我還不知道它有這個入口。


為什麼 Component 會提供這麼多 Props?

因為一個共用 Component 不可能把每一個專案需求都寫死。

它通常會設計成:

預設行為
+
可配置參數

例如:

<MyComponent
  editable
  disabled
  loading
  formatter={...}
/>

所以 Props 本質上可以理解成:

Component 留給外部調整行為的入口。


這也讓我重新理解 Props

前面我們學 Props 時:

Parent
↓
Props
↓
Child

比較像是在理解:

資料怎麼傳。

但在 Component Library 裡,

Props 還有另一個很重要的角色:

Configuration。

例如:

<Input
  disabled
/>

disabled 不只是資料。

它是在告訴 Component:

這次請用「不可編輯」的模式運作。


所以讀 Component 時,我現在會分兩種 Props

第一種:

Data Props

例如:

value={user.name}

代表:

我要顯示什麼資料。

第二種:

Behavior / Configuration Props

例如:

disabled
loading
multiple
formatter

代表:

Component 要怎麼運作。

這個區分讓我讀第三方元件時清楚很多。


如果原本 Component 已經能做到,為什麼優先沿用?

因為它通常已經處理過:

型別
邊界值
Form 整合
錯誤狀態
既有樣式
專案一致性

如果只是少一個參數,

例如:

<MyInput
  someOption
/>

那通常比:

把整個元件換掉
+
重新實作原本能力

風險低很多。


但這也不是說「永遠不能重做」

如果確認:

現有 Component 本身不適合需求
Props 無法支援
硬改會讓 API 很奇怪
需求已經偏離原元件責任

那重做或抽新的 Component 完全合理。

真正的差別是:

我理解它做不到
↓
所以替換

而不是:

我不知道它能不能做到
↓
直接替換

這兩種做法看起來很像,工程判斷完全不同

第一種

不知道元件能力
↓
重做

比較像:

在資訊不足時做決策。

第二種

確認現有能力
↓
評估成本
↓
決定沿用或替換

這才比較像:

有意識地做工程選擇。


這也是我現在很常問自己的問題

看到需求時,不要馬上問:

我要怎麼寫?

而是先問:

專案裡已經有什麼?

這個 Component 原本解決什麼?

它有哪些擴充入口?

真的需要新增一套嗎?

很多時候,

找到正確的 existing API,

比自己多寫 50 行 Code 還重要。


這種錯誤其實很容易發生在 AI 時代

現在有 AI 幫忙,

只要說:

幫我做一個符合這個需求的 Input。

很快就能產生一套新的實作。

問題是 AI 不一定知道:

你的專案裡已經有一個 Component
你的套件已經有一個 Prop
你們團隊已經有既有 Pattern

如果沒有先理解 Codebase,

很容易變成:

需求
↓
AI 產新 Code
↓
功能能跑
↓
但專案裡多了一套重複邏輯

所以 AI 越方便,

反而越需要問:

這段東西真的需要重新寫嗎?


我現在會用這個順序處理 Component 需求

需求來了
↓
確認目前使用的 Component
↓
看 Import
↓
看 Component Source / Documentation
↓
搜尋 Existing Usage
↓
確認 Props / API
↓
能設定解決?
├─ Yes
│  ↓
│  優先沿用
│
└─ No
   ↓
   評估 Wrapper / Extend / Replace

這條流程其實比:

直接開始 Coding

更重要。


今天真正想記的是

看到現有 Component 不符合需求時,

先不要急著:

拆掉
重寫
換成最原始 Input

先問:

我是真的確認它做不到,還是我只是還沒看懂它?

因為成熟的開發不只是:

能不能把功能做出來。

還包括:

能不能利用已經存在的能力,用更小的修改完成需求。

我現在越來越覺得,

「少寫一段不必要的新 Code」

有時候比:

「成功寫出一段新 Code」

更像是在進步。

下一篇可以接一個跟今天很像、但更進一步的工程判斷:

套件明明可以硬改到符合需求,但為什麼最後反而選擇換一種元件?


上一篇
Day 23|使用者還沒打完,你就先報錯了?Input 其實也有操作生命週期
下一篇
Day 25|套件明明可以硬改,為什麼最後反而選擇換一種元件?
系列文
從 UI/UX 麻瓜到工程魔法師|從讀懂程式開始 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言