今天要來介紹一個我們在寫 React Component 很重要的觀念,就是讓 Component 保持純淨(Pure)。前面的文章就有提到在寫 Component 就跟寫 JavaScript function 一樣,而我們在寫 function 的時候,有時候會把 function 寫成純函式(Pure Function),同理 Component 也會有純的。
純函式簡單的來說,就是我們給 function
什麼樣的參數(parameter),他就會回傳(return)一樣的回傳值,就像是數學公式。例如 y=2x
,只要 x = 2
,那麼 y = 4
,不管傳幾次 x = 2
,都會得到一樣的答案。另一個特徵就是他不會修改任何在他被呼叫之前就已經存在的 object
或變數。在呼叫 function
前到執行完成後,原本已經存在的變數都不會因此而改變。
舉一個範例:
function getBattingAverage(hits, ab) {
return hits / ab;
}
上面的是打擊率的計算公式,雖然會有不同的打者,但只要他們的安打數 hits
,跟打數 ab
是一樣的,那他們的打擊率就都會是一樣的。
而 React 中的 Pure Component 也是同樣的概念,會希望只要傳入相同的 props
,就能回傳相同的 JSX。
function BattingStats({ hits, ab }) {
return (
<ol>
<li>安打數:{hits}</li>
<li>打數:{ab}</li>
<li>打擊率:{hits / ab}</li>
</ol>
)
}
function App() {
return (
<section>
<h1>成績比較<h1>
<h2>球員 A</h2>
<BattingStats hits={3} ab={8} />
<h2>球員 B</h2>
<BattingStats hits={1} ab={9} />
</section>
)
}
當我們把相對應的 hits
跟 ab
傳入 BattingStats
時,不管是 球員A 還是 球員B,只要數值是一樣的,產生出來的 UI 都會長一樣。
如果一個 function 在使用相同變數下,回傳不同的結果,這樣我們就會撐這個 function 會具有 Side Effects,比較常見的就是使用 function 外的變數並且在裡面改變數值。這樣的話會容易使使用者感到困惑,因為每次使用一樣資料的結果,但都會產生不同的結果。這樣會影響到我們在開發的時候,尋找問題點的時候的困擾。
React Component 也是,會希望每個 Component 專心的在處理自己的計算,Component 之間彼此獨立計算不受到其他影響。
但是在開發的時候,為了一些互動像是開關表單、動畫,更新資料庫等,這些都是 Side Effects,我們不希望他們在 render 的時候發生,所以通常會讓這些 side effects 在 Event Handler 裡面進行。通常使用在點擊按鈕,輸入資料等情境。儘管 event handler 是在 component 內部定義的,但它們不會在 render 時間執行!所以 event handler 不需要是 pure 的。
如果我們的使用情境,無法使用 event handler 來處理,React 也提供使用 component 中的 useEffect
來執行 side effect 改變 Component 裡的 JSX。這在之後的篇章會用到,但是這也是最後的手段,盡量能不用就不用。
最後來提到為什麼讓 Component 是 Pure 的那麼重要,有幾個面向:
今天介紹的 pure function 概念,其實不只寫 React,在其他地方的程式設計也會時常用到,像是 functional programming 也非常注重這個項目。所以大家在寫 Component 的時候,不仿想想自己寫的 Component 是不是 Pure 的,或是是不是真的需要用到 Side Effect,這樣對自己的寫出來的程式碼品質一定會越來越好的。
以上就是今天文章的全部內容,感謝大家耐心地看完,有任何問題與建議都歡迎告訴我,明天見,晚安。