前言
在寫這系列文章的過程中,漸漸體會到 React 每個概念間的環環相扣,今天想跟大家分享一個在實務開發中經常會用到的重要概念:「狀態提升(Lifting State Up)」。
這個概念初次接觸時可能會覺得有點抽象,但其實它就像是一個團隊裡的溝通機制。想像一下,如果團隊中每個人都自己做決定,沒有互相溝通,那麼最後的成果可能會不太協調。但如果我們有一個共同的主管來協調大家的工作,事情就會順暢許多。在 React 的世界裡,「狀態提升」就扮演著這樣的角色。
為什麼需要狀態提升?
讓我們用一個簡單的手風琴選單(Accordion)來理解這個概念。
假設我們有這樣的需求:一次只能展開一個面板,當點擊另一個面板時,原本開啟的要自動關閉。
最直覺的作法可能是讓每個面板(Panel)自己管理自己的狀態:
1 | function Panel({ title, children }) { |
這樣寫看起來沒什麼問題,但實際使用時你會發現:因為每個 Panel 都各自管理自己的狀態,所以無法實現「只展開一個面板」的需求。就像每個人都自己做決定,沒有人能統籌全局一樣。
實作狀態提升
為了解決這個問題,我們需要把狀態提升到父元件:
1 | function Accordion() { |
這樣的改動帶來了幾個重要的變化:
- Panel 元件變成了「受控元件」,它的行為完全由外部控制
- 所有面板共用同一個狀態,確保一次只能展開一個
- 資料流向變得更清晰,更容易追蹤和除錯
狀態該放在哪裡?
在實務開發中,經常會遇到「這個狀態該放在哪裡」的問題。其實可以用一個簡單的原則來判斷:
找出所有需要這個狀態的元件,然後找到它們最近的共同父元件,通常這個父元件就是放置狀態的最佳位置。
就像我們的範例中,兩個 Panel 都需要知道「現在是否該展開」,所以我們把狀態放在它們的父元件 Accordion 中。
總結
狀態提升不只是一個技術概念,更是一種讓元件之間能夠優雅協作的設計模式。透過將需要共享的狀態提升到合適的層級,我們可以:
- 讓元件之間的互動變得可能
- 維持單一資料來源
- 讓應用程式的資料流向更清晰
當然,這不是說所有狀態都要往上提升。有些純局部的狀態(例如表單的暫時輸入值)放在當地管理反而更合適。關鍵是要為每個狀態找到最恰當的位置,讓整個應用程式的架構更加合理且易於維護。