在前面的篇章:Day 25 - 在 Component 之間共享 State,有介紹 state 可以透過 props
傳下去給其他 Component 使用。但有時候在一些情境下,會有想使用相關 state 的 component 在比較深層的地方,如果要用 props
去傳遞給他使用的話,就需要經過很多個 component 才能傳遞到。這樣會在我們開發的時候花更多時間,在追蹤來源的時候可能也會更麻煩,為了避免這樣的情況,今天就要介紹另一個 React 的功能 Context。
今天的文章參考官方文件的:
Context 的概念有點像是,會有個 parent component 提供資訊讓從他開始的 tree 裡的 component 都可以使用那個資訊,就不需要一層一層的傳遞,變成是 tree 裡的想要就直接 use
就好了。
要使用 Context 有以下步驟:
要建立一個新的 context,要使用到 React 的 createContext
function:
import { createContext } from 'react';
export const LevelContext = createContext(1);
createContext
裡會需要傳入一個參數,這個就會是 context 的預設值。另外我們命名習慣會把 context 跟 component 命名一樣都會是大寫開頭後面是 camelCase。
跟 useReducer
一樣,如果我們要使用 context 的話,就也要在 component 裡面使用 hook useContext
去獲得 context 資料:
const level = useContext(LevelContext);
這時候因為還沒有在 Parent component 提供資訊,所以目前使用 useContext
都會回傳預設值,剛剛的範例的話就是 1
,所以接下來就是步驟 3
我們建立的 LevelContext
除了給 useContext
用之外,也可以在 component 裡面用像是 component 的方式使用 JSX 裡:
<LevelContext value={level}>
{children}
</LevelContext>
被它包住的 children 裡的 component 就都能從 LevelContext
這個提供者獲得 context 資訊,然後可以透過傳入 value
去覆蓋原本的預設值。
另外就是在同一個 tree 裡面可以在不同層使用 LevelContext
去包 children 然後傳入不同的 value
,這樣的話 useContext
會去找離他最近的 LevelContext
去找 context 的值。再來就是不同的 context 是各自獨立的,不會互相影響,所以也不會覆蓋彼此。
在使用 context 之前,可以先想想是不是真的需要用它,有時候 props 就是會需要各層使用,所以需要一層一層傳遞下去也是有可能的,這時候因為不用特別跳過中間的 component,所以可以不一定要使用 context。
再來就是我們可以借用 component 的 children 讓其他下層的 component 直接從 Parent component 獲得資料,譬如說 <Layout posts={posts} />
可以改成 <Layout><Posts posts={posts} /></Layout>
這樣就不用透過 Layout
這個 component 把 posts
傳下去。
還有一些情境我們會考慮使用 context
最後要注意的是,如果在 context 的提供者改變 context 內容的話,所有使用 useContext
的 component 都會重新 render,這也會變成我們考量是否需要使用 context 的原因之一。
今天介紹如何跨 component 的溝通的 react context,只要熟練的話,在 component 提取想要的資訊就會變得更方便與快速。
今天的文章就先介紹到這邊,感謝大家耐心地看完,如果有任何問題與建議,歡迎留言告訴我,明天見,晚安。