我們知道元件之間是互相獨立的,唯一的溝通方式就是透過 props 來傳遞資料,而且傳遞資料的方向是單一由上而下,也就是說只能由父元件傳遞資料給子元件,而不能由子元件傳遞給父元件,這樣做是為了保持單向資料流的特性,提高程式碼的維護性。
但 props 傳遞資料有一個缺點,那就是資料流一定要是連續的,這是什麼意思呢?舉個例子,假如我們有一個元件樹長這個樣子,其中左下角的元件具有一份 user 的資料:
到目前為止沒有什麼問題,但如果右下角的元件也需要顯示 user 的資料呢?那就讓右下角的元件也保管一份 user 的資料不就好了嗎?
這樣違反了 SSOT 原則,缺點是我們要同時管理兩份 user 資料,一旦其中一份 user 資料更新,就要讓另外一份 user 資料也跟著跟新,確保兩份 user 資料是同步的,這樣兩份資料顯示在網頁上才不會有不一致的情況發生。
在 React 的框架下要解決這個問題的作法,就是將這兩份 user 資料往上提,提到這兩個元件的共同祖先元件,也就是最上面的那個元件,如此我們只需要保管一份 user 資料,然後再透過 props 往下傳即可:
乍看之下也沒有什麼問題,但我們再進一步假設如果我們的元件樹越長越深呢?有可能就會為了將 user 的資料傳遞到需要的元件,而造成中間的元件都要負責接收並且傳遞這一份資料,如此一來就會有很多不必要的 props 傳遞:
於是,context 就這樣誕生了。
context 可以讓我們用有別於 props 的方式來傳遞資料。
我們可以透過 context 決定資料要傳遞的範圍,並且在需要該份資料的元件中取得,完全不會影響中間的原件。
首先建立一個 context:
const MyContext = React.createContext(defaultContext);
接著再最上層的元件使用:
<MyContext.Provider value={contextValue}>
</MyContext.Provider>
然後在需要取得該 context 值的元件中使用:
const contextValue = useContext(MyContext);
即可取得該 context 值。