onClick 還是 handleClick?淺談 React 事件處理的命名慣例
前言:
隨著 React 開發經驗的累積,我開始對專案中命名原則的一致性這件事越來越在意。在維護公司專案時常常會看到同樣是事件處理函數,有的地方以onXXX命名 ,有的地方則是handleXXX。這樣的情況在定義 props 時尤為明顯:假設一個 callback function 要從元件 A 傳到 B 再傳到 C,明明傳遞的是同一個東西,但在元件 B 的 props 中叫做onXXX,到了元件 C 又被改命名為handleXXX,導致我在追蹤程式邏輯時不免覺得煩躁。雖然命名上並沒有所謂的「正確答案」,但為了理清思緒並統一我自己寫程式的命名風格,我整理了 React 社群中關於事件處理命名的常見慣例,也分享一些自己的理解,希望能幫助讓程式碼更具一致性與可讀性。
React 中的事件與事件處理
在討論 onXXX 和 handleXXX 的命名慣例之前,我們需要先區分兩個重要的概念:事件 (Event) 和 事件處理函數 (Event Handler)
-
事件 (Event)
事件是應用程式中由使用者操作觸發的行為,例如點擊按鈕、改變輸入框內容、或者提交表單。React 通過 SyntheticEvent 將瀏覽器的原生事件包裝起來,為我們提供跨瀏覽器一致的事件行為處理。 -
事件處理函數 (Event Handler)
事件處理函數是程式碼中用來回應事件的邏輯。簡單來說,它是一段「事件發生後執行什麼」的程式碼。例如:function handleClick() {
console.log('Button was clicked!');
}
容易引起疑惑的事件處理命名
當事件處理函數需要跨元件傳遞時,命名上的選擇往往會帶來困擾:
-
父元件定義了一個事件處理函數,應該命名為
handleClick還是onClick?
如果命名為onClick,可能會與 HTML 屬性混淆,但命名為handleClick,又似乎少了一些「事件觸發」的語意。 -
子元件接收到 props,應該命名為
onClick還是handleClick?
作為一個暴露的 API,onClick更符合直覺,但內部若混用handleClick來處理邏輯,命名一致性可能會出現問題。
這邊舉一個我在工作時常遇到的例子。
你可以停下來數數看同個 callback function 在傳遞的過程中換過幾次名字:
function GrandParent() {
const onClick = () => console.log("Button clicked!"); // GrandParent 命名了一個叫做 "onClick" 的 callback function
return <Parent handleClick={onClick} />; // GrandParent 把 "onClick" 作為 Parent 期望接收到的 "handleClick" 傳遞給 Parent
}
function Parent({ handleClick }) {
return <Child handleSuccess={handleClick} />; // Parent 把接收到的 "handleClick" 作為 Child 期望接收到的 "handleSuccess" 傳遞給 Child
}
function Child({ handleSuccess }) {
return <button onClick={handleSuccess}>Click me</button>; // Child 把接收到的 "handleSuccess" 綁定到 button 的 onClick 事件上
}
嗯,沒錯,3 次喔 ...
從上面的例子可以知道,當沒有一致的事件處理命名風格時,三個 Components 就足以讓你感到困惑了,更不用說工作時面對的商業級別規模的專案,trace code 起來只有滿滿的心累...
React 中 的事件命名慣例
命名問題的核心:語意與責任的混淆
說到事件處理的命名問題,其實背後主要圍繞兩個核心概念:語意性和責任清晰性。
- 語意性:好的命名應該能直觀地表達這段程式碼的用途,讓開發者在閱讀時一目了然。例如,
handleClick就能很清楚地表示這是一個用來處理點擊事件的函數,而onClick則能直接聯想到這是點擊事件的入口。 - 責任清晰性:命名應該反映程式碼的責任範疇,讓人知道這段程式碼的職責是什麼。特別是在 callback function 被多層傳遞的情況下,名稱需要保持一致,否則不僅會增加閱讀負擔,也容易讓開發者對事件的流向感到困惑。
舉例來說,當父元件定義一個函數時,應如何命名才能清楚地表達這個函數的處理邏輯?而子元件暴露的 props,則應如何命名才能讓人一眼看出它是事件觸發的入口?如果這些細節處理不當,程式碼的可讀性和維護性就會大大降低。