30 天前,我最常做的事情,是從第一行開始看。
看到:
const { loading, run } = useRequest(...)
我會開始:
loading 是什麼?
run 是什麼?
useRequest 又是什麼?
async 又是什麼?
onSuccess 是什麼?
每個字都想先弄懂。
結果常常變成:
單字查了一堆
↓
語法也查了一堆
↓
但整段到底在幹嘛
還是不知道
那時候我以為:
看懂程式碼,就是把每一行都翻譯成中文。
但 30 天寫到今天,我慢慢發現:
真正讓我開始看懂程式的,不是翻譯每一行,而是找到它們之間的關係。
例如:
const { data, loading, run } = useRequest(
() => UserService.getById(id),
{
manual: true,
onSuccess: result => {
setUser(result)
}
}
)
以前我會先拆:
const 是什麼?
{} 是什麼?
data 從哪來?
loading 是什麼?
run 是什麼?
useRequest 是什麼?
箭頭函式是什麼?
這些問題都沒有錯。
但如果同時全部追,
很容易越查越散。
我可能還是不認識所有語法。
但會先看:
誰觸發?
資料從哪裡來?
Request 在哪裡?
Response 回來去哪?
最後誰使用這份資料?
例如剛才那段:
run()
↓
觸發 useRequest
↓
UserService.getById(id)
↓
API
↓
Response
↓
onSuccess(result)
↓
setUser(result)
↓
State 更新
↓
畫面重新 Render
流程先抓到之後,
才回去補:
解構
useRequest
async
型別
我反而比較不容易迷路。
我們確實碰過很多東西:
State
Props
Context
useEffect
useRequest
map
spread
key
null
undefined
??
?.
URL Params
Controlled Component
IME
Route
Permission
iframe sandbox
但如果最後只記住這些名詞,
這 30 天對我來說其實還不算真正有收穫。
因為下一個專案,
一定還會出現:
我沒看過的 Hook
我沒看過的 Library
我沒看過的 Component
我沒看過的 Backend API
不可能把所有東西先背完才開始工作。
所以真正值得留下來的,
應該是一套:
遇到陌生 Code 時,我知道先從哪裡開始。
現在拿到一個陌生頁面,
我不會第一眼就開始逐行看。
會先找:
這個檔案是什麼?
Page?
Component?
Hook?
Service?
Utility?
如果是 Page,
再找:
import 了什麼?
主要 Render 哪些 Component?
資料在哪裡取得?
Submit 在哪裡?
先建立一個大概地圖。
很多程式其實都可以先問:
這段什麼時候會跑?
例如:
onClick={handleSave}
就是:
使用者點擊
↓
handleSave()
例如:
useEffect(() => {
fetchData()
}, [])
就是某個 Effect lifecycle。
例如:
manual: true
則代表:
不會自己跑
↓
我要去找誰呼叫 run()
光是找到 Trigger,
很多 Code 就突然開始有順序了。
以前看到:
customer.name
我會直接看:
name 是什麼?
現在會先問:
customer 從哪來?
可能是:
Props
State
Context
API Response
Form
URL Param
來源不同,
Debug 的方向就完全不同。
拿到 Response 之後,
也不能只停在:
API 成功了。
還要看:
Response
↓
setState?
↓
form.setFieldsValue?
↓
dataSource?
↓
Context?
↓
直接 Render?
因為很多 Bug 並不是:
沒有資料。
而是:
資料有回來,但後面走錯地方。
這是我到後面才越來越有感的東西。
資料經過不同邊界時,
常常會變形。
例如:
Array
↓
URL
↓
String
例如:
Form ""
↓
Payload undefined
↓
JSON 裡欄位消失
例如:
Route /users/create
↓
Dynamic Param
↓
id = "create"
所以我現在會特別注意:
Form → Request
State → URL
Frontend → Backend
Backend → Response
HTML → Browser
每跨一層,
就問一次:
值還是一樣嗎?型別還是一樣嗎?語意還是一樣嗎?
這可能是我最想帶走的一個習慣。
例如:
API 重複打
以前:
想辦法不要打第二次。
現在:
為什麼第二次會被觸發?
↓
Component remount?
Effect?
Request lifecycle?
例如:
Input 閃了一下
以前:
是不是 Render 太快?
現在:
哪個 State 控制 Input?
↓
誰先寫 ID?
↓
誰後寫 Name?
例如:
API 400
以前:
Backend 怎麼壞了?
現在:
Request Payload 真正送什麼?
↓
這個參數從哪來?
↓
URL 還原後型別對嗎?
問題不再只是:
哪裡壞了?
而是:
第一個錯誤是從哪裡開始的?
做到後面,
我也開始碰到:
方案 A 可以
方案 B 也可以
例如:
繼續客製 RangePicker
或:
拆成兩個 DatePicker
這時候就不是:
哪個語法比較正確?
而是:
哪個比較符合資料模型?
哪個比較容易維護?
哪個 Edge Case 比較少?
哪個跟現有專案比較一致?
也就是:
Trade-off
開始出現了。
以前拿到需求,
很容易想:
我要新增什麼 Code?
但現在會先看:
現有 Component 有沒有 Prop?
專案裡有人做過嗎?
有沒有既有 Utility?
是不是只差一個設定?
有時候最後只改:
someProp={true}
比重做一整個 Component 更好。
這種時候:
少寫 Code,不代表做得比較少。
有可能代表:
我開始比較理解現有系統了。
這一年工作上很難完全不碰 AI。
以前比較容易:
看不懂
↓
整段貼給 AI
↓
請它改
↓
跑得動
↓
結束
但這樣有一個問題:
下一次遇到類似問題,我還是不知道怎麼開始。
現在我比較希望變成:
先自己畫流程
↓
找出目前卡住的點
↓
提出假設
↓
再讓 AI 幫我檢查
例如:
我懷疑這裡是 remount 導致 Request 重打,可以幫我看這個判斷有沒有漏掉什麼?
這種問法和:
幫我修。
感覺差很多。
AI 還是很有用,
只是我希望它越來越像:
一起 Debug 的工具
而不是:
替我看懂所有東西的人。
我會先跑這一套:
1. 怎麼重現?
2. 正常情況應該怎麼走?
3. 誰觸發?
4. 資料從哪來?
5. Source of Truth 是誰?
6. 中間經過哪些轉換?
7. Network 真正送什麼?
8. Response 真正回什麼?
9. 第一個不符合預期的地方在哪?
10. 修法是在解 Root Cause,
還是只壓住症狀?
如果完全看不懂,
那就先畫:
Input
↓
Event
↓
State / Form
↓
Service
↓
Request
↓
Backend
↓
Response
↓
Render
不一定每個 Case 都有全部這些層。
但先把自己知道的節點放上去,
通常就比盯著整份 Code 有方向。
30 天並沒有讓我突然變成:
什麼 Code 都看得懂的工程師。
像是:
更複雜的非同步處理
React 效能
useMemo / useCallback
TypeScript Generic
更深的 Backend
系統架構
資安
還有很多東西要補。
但我現在對「看不懂」這件事,
感覺和 Day 01 已經不太一樣。
Day 01 的:
看不懂
比較像:
我連從哪裡開始都不知道。
現在的:
看不懂
比較像:
我知道自己卡在哪一層,可以一層一層查。
對我來說,
這個差異已經很大了。
一開始從 UI/UX 轉工程,
很容易覺得自己以前的經驗是不是:
全部歸零。
但做到後面,
我反而越來越常把以前的思考帶進來。
例如:
使用者還在輸入時,
真的要立刻顯示 Error 嗎?
例如:
這個 Component 的互動模型,
真的符合使用者正在完成的任務嗎?
例如:
沒有權限的人,
UI 應該看到什麼?
以前是在設計畫面。
現在則多了一層:
這個畫面背後的 State 怎麼走?
事件什麼時候發生?
資料怎麼存?
API 怎麼接?
安全邊界在哪?
不是把 UI/UX 丟掉重新開始。
比較像是:
開始學會往畫面後面再多看幾層。
如果要把這 30 天濃縮成一個對照,
大概會是:
看到陌生 Code
↓
從第一行開始
↓
每個單字都查
↓
越查越散
↓
還是不知道整段在幹嘛
看到陌生 Code
↓
先看它的責任
↓
找 Trigger
↓
找資料來源
↓
追資料去向
↓
畫出流程
↓
真的需要時才補語法
我不是突然知道所有答案了。
只是開始知道:
我要問哪些問題。
30 天前,我寫:
原來我看不懂的,不是語法,是流程。
30 天後,我會再補一句:
語法還是要學,但流程會告訴我現在最值得先學哪一個。
因為真正的專案不會等我把 JavaScript、React、TypeScript、Backend 全部學完才開始。
一定永遠都會遇到陌生東西。
所以比起:
把所有咒語背完。
我更希望自己留下來的是:
看到陌生 Code
↓
不慌著從第一行開始
先找入口
↓
找 Trigger
↓
找資料
↓
找邊界
↓
找第一個不符合預期的地方
然後再一點一點把不知道的地方補起來。
最開始參加鐵人賽,
我不是因為覺得自己已經會很多東西。
反而是因為:
有太多東西看不懂,所以想逼自己每天整理一點。
寫到最後,
答案也不是:
我現在會了。
比較像:
我現在知道怎麼繼續學了。
對一個從 UI/UX 開始、一路走進工程的人來說,
我覺得這已經是一個很好的開始。
如果未來又碰到一段完全看不懂的 Code,
我想我還是會卡。
還是會查。
還是會問。
但至少下一次,
我不會再只盯著第一行了。