經過前幾天的努力,我們的系統在功能與畫面上都已經相當完整。但是,隨著專案越來越大,可能會發現一個有點惱人的現象:我們的 medications 狀態和 setMedications 函式,都統一放在 App.jsx 裡,然後像接力賽一樣,透過 Props 一層一層往下傳遞給 AddMedicationForm、MedicationList 等元件。
這種把狀態一層層往下遞的現象,在 React 中被稱為 「Prop Drilling (屬性向下鑽取)」。當元件只有一兩層時還好,但如果未來我們要新增「設定頁面」或「個人資料頁面」,這會讓程式碼變得非常冗長且難以維護。
為了解決這個問題,今天我們要使用 React 內建的強大武器:Context API,來建立一個「全域狀態管理中心」。
Step 1:建立全域狀態中心 (Context)
首先,在 src 資料夾下新增一個名為 context 的資料夾,並在裡面建立一個檔案:MedicationContext.jsx。
我們要將原本寫在 App.jsx 裡面關於 medications 的狀態、LocalStorage 存取邏輯,以及自動排序的邏輯,全部搬到這裡集中管理:

Step 2:用 Provider 包覆整個應用程式
接著,請打開 src/main.jsx。我們要在最外層套上剛剛做好的MedicationProvider,這樣整個專案內的任何元件,就都有權限去「領取」用藥資料了。
Step 3:幫 App.jsx 瘦身!
現在,App.jsx 不再需要自己管理狀態,也不需要再把 props 傳給子元件了!請打開 src/App.jsx,把原本的狀態邏輯都刪掉,你會發現程式碼變得無比乾淨:
Step 4:在子元件中使用 useContext 取代 Props
最後,我們只要在需要用到資料的元件裡,把資料「呼叫」出來即可。記得在元件最上方引入 useContext 和 MedicationContext。
以 AddMedicationForm.jsx 為例:
特別注意:排序資料的應用
在 MedicationList.jsx 中,除了提取 medications 和 setMedications,我們還要記得提取 sortedMedications,並且把底下渲染清單的陣列改成它,這樣清單才會正確照時間排序喔!
這樣今天的任務就完成了。