iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0
Modern Web

重溫 React 官方文件回到最初的起點系列 第 28

Day 29 - 使用 Context 深度傳遞資料

  • 分享至 

  • xImage
  •  

在前面的篇章:Day 25 - 在 Component 之間共享 State,有介紹 state 可以透過 props 傳下去給其他 Component 使用。但有時候在一些情境下,會有想使用相關 state 的 component 在比較深層的地方,如果要用 props 去傳遞給他使用的話,就需要經過很多個 component 才能傳遞到。這樣會在我們開發的時候花更多時間,在追蹤來源的時候可能也會更麻煩,為了避免這樣的情況,今天就要介紹另一個 React 的功能 Context
今天的文章參考官方文件的:

Context:另一個方法去傳送 props

Context 的概念有點像是,會有個 parent component 提供資訊讓從他開始的 tree 裡的 component 都可以使用那個資訊,就不需要一層一層的傳遞,變成是 tree 裡的想要就直接 use 就好了。
要使用 Context 有以下步驟:

  1. 建立 一個新的 context
  2. 使用 context 在需要資訊的 component
  3. 提供 資訊在有資訊的 Parent component

1. 建立一個新的 context

要建立一個新的 context,要使用到 React 的 createContext function:

import { createContext } from 'react';

export const LevelContext = createContext(1);

createContext 裡會需要傳入一個參數,這個就會是 context 的預設值。另外我們命名習慣會把 context 跟 component 命名一樣都會是大寫開頭後面是 camelCase。

2. 使用 context 在需要資訊的 component

useReducer 一樣,如果我們要使用 context 的話,就也要在 component 裡面使用 hook useContext 去獲得 context 資料:

const level = useContext(LevelContext);

這時候因為還沒有在 Parent component 提供資訊,所以目前使用 useContext 都會回傳預設值,剛剛的範例的話就是 1,所以接下來就是步驟 3

提供資訊在有資訊的 Parent component

我們建立的 LevelContext 除了給 useContext 用之外,也可以在 component 裡面用像是 component 的方式使用 JSX 裡:

<LevelContext value={level}>
  {children}
</LevelContext>

被它包住的 children 裡的 component 就都能從 LevelContext 這個提供者獲得 context 資訊,然後可以透過傳入 value 去覆蓋原本的預設值。

另外就是在同一個 tree 裡面可以在不同層使用 LevelContext 去包 children 然後傳入不同的 value,這樣的話 useContext 會去找離他最近的 LevelContext 去找 context 的值。再來就是不同的 context 是各自獨立的,不會互相影響,所以也不會覆蓋彼此。

使用 context 的情境

在使用 context 之前,可以先想想是不是真的需要用它,有時候 props 就是會需要各層使用,所以需要一層一層傳遞下去也是有可能的,這時候因為不用特別跳過中間的 component,所以可以不一定要使用 context。

再來就是我們可以借用 component 的 children 讓其他下層的 component 直接從 Parent component 獲得資料,譬如說 <Layout posts={posts} /> 可以改成 <Layout><Posts posts={posts} /></Layout> 這樣就不用透過 Layout 這個 component 把 posts 傳下去。

還有一些情境我們會考慮使用 context

  • 外觀主題(Theming):像是網站會有 夜間模式(Dark Mode),需要在各個 component 改變呈現外觀的資訊。
  • 用戶(Account):在網站中會記錄當下的使用者是誰,也會需要在網站的各處使用,所以也是很適合使用 context 的地方。
  • 路徑(Routing):在管理網站中的各個路徑資料,紀錄當下使用者停留在哪個頁面路徑,也會需要 context 這種全域的紀錄
  • 管理 State:當我們的程式越來越大,state 影響的範圍也會變大,只存在 component 本身的可能會不夠用,這時候就可能需要 全域的 state(global state),這時候就可以搭配著 context 使用。明天的篇章也會介紹如何讓 context 跟 reducer 結合在一起。

最後要注意的是,如果在 context 的提供者改變 context 內容的話,所有使用 useContext 的 component 都會重新 render,這也會變成我們考量是否需要使用 context 的原因之一。

小結

今天介紹如何跨 component 的溝通的 react context,只要熟練的話,在 component 提取想要的資訊就會變得更方便與快速。
今天的文章就先介紹到這邊,感謝大家耐心地看完,如果有任何問題與建議,歡迎留言告訴我,明天見,晚安。


上一篇
Day 27 - 將 State 邏輯提取到 Reducer
系列文
重溫 React 官方文件回到最初的起點28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言