在 Context API 和 Redux 之間做出選擇

Irakli Tchigladze 2023年1月30日
  1. 在 React 中使用 Context API
  2. 在 React 中使用 React.createContext()
  3. 在 React 中使用 useContext() 鉤子
  4. 在 React 中使用 Redux 庫
  5. 何時使用 Context API 與 React 中的 Redux
在 Context API 和 Redux 之間做出選擇

React 是最流行的 JavaScript 框架之一,因為它為 Web 應用程式建立了可重用的 UI 元件。它很容易與其他庫整合,並提供了很大的靈活性。

React 應用程式通常具有一個父元件和多個子元件。將資料從父元件傳遞給子元件的預設方式稱為 props

此功能對於元件的可重用性至關重要,元件是 React 應用程式的構建塊。每個元件都接受執行特定操作所需的資料,並且可以擁有子元件並使用 props 傳遞資料。

如果你的 React 應用程式有一個簡單的元件樹,你可以使用 props 手動傳遞資料。然而,隨著應用程式的增長,元件樹變得更加複雜。

在某些時候,子元件將擁有自己的子元件。找到具有複雜元件層次結構的元件樹並不少見。

在 React 中使用 Context API

複雜應用程式的元件樹很難遍歷。在這種情況下,通過樹的每個分支手動傳遞 props 是不切實際的。

Context API 是一種將 props 從樹頂部的父元件 傳遞到其子元件 的解決方案。

你可以使用 Context API、常規 propsRedux 來傳遞 props。關鍵是要知道每個人的優點並充分利用它們。

Context API 有助於在不同的樹枝上傳遞大多陣列件所需的特定 props。例如,在 React 應用程式的大多陣列件中都需要諸如區域設定偏好之類的值。

從技術上講,你可以使用 props 傳遞資料,但是導航元件樹及其許多分支將花費太多時間。

相反,你可以使用 Context API 將資料從父元件直接傳遞給元件樹較低階別的子元件。

讓我們看一個簡單的例子:

import "./styles.css";
import React from 'react'
import { useContext } from 'react'
const sampleContext = React.createContext()

export default function App() {
  return (
    <sampleContext.Provider value={10}>
    <div className="app">
      <Child></Child>
    </div>
    </sampleContext.Provider>
  );
}
function Child() {
  return (
    <div className="child">
      <Grandchild></Grandchild>
    </div>
  );
}
function Grandchild() {
  const value = useContext(sampleContext)
  return <div className="grandchild" style={{fontSize: 30}}>{value}</div>;
}

在這裡,我們有三個元件:位於樹頂部的 App 元件、Child 元件和 Grandchild 元件。

Grandchild 元件位於元件樹的底部,可以直接訪問父元件的 value 屬性。prop 值不必手動通過每個樹級別。

.createContext() API 帶有核心 React 庫,因此我們必須先匯入它。然後我們建立一個 sampleContext 變數,它將儲存 Context object

最後,我們從核心 React 庫中匯入 useContext() 鉤子,我們將使用它從 Context API 中獲取值。你可以檢視實時 codesandbox

在 React 中使用 React.createContext()

React.createContext() 是返回 Context object 的主要方法。儲存返回物件的變數應該在元件定義之外建立。

useEffect() 掛鉤僅用於從 Context object 獲取值,而不是建立它。React.createContext() 採用一個引數:Context object 的預設值。

如果子元件在其樹中沒有提供者,React 只會讀取預設值。出於這個原因,React 開發人員經常使用預設值來隔離測試元件。

Context object 包含一個自定義 Provider 元件。它允許子元件訂閱上下文物件中的值。

如果將 contextType 屬性設定為上下文物件,你可以通過讀取元件的 this.context 屬性來訪問 Provider 元件的值。

不幸的是,你只能訂閱一個 Provider 元件。你可以為不同的上下文物件建立多個自定義提供程式元件。

這些可以巢狀在元件樹中的各個級別。在這種情況下,子元件將讀取最近的父元件的自定義 Provider 元件的值。

Provider 元件採用一個 value 屬性,它可以分配一個你需要在子元件中訪問的值。只要它的後代在元件樹中,它就可以同時連線到多個孩子。

每次 Provider 元件的 value 屬性發生變化時,所有訂閱它的子元件都會重新渲染。通常,React 中的元件重新渲染由 .shouldComponentUpdate() 方法處理。

但是,此方法不處理使用來自 Provider 的值的子元件的更新。相反,子元件將先前的值與新的值進行比較並更新任何更改。

由於重新渲染不是由 .shouldComponentUpdate() 方法處理的,父元件的重新渲染不會自動重新渲染子元件。

在 React 中使用 useContext() 鉤子

有多種方法可以使用 Context 物件中的值。

首先,你可以設定類元件的 contextType 屬性。它必須設定為上下文物件。

訪問該值的第二種方法是使用 Context.Consumer 自定義元件。此自定義元件的子元件必須是適合功能元件的函式。

然而,訂閱 Provider 元件的最簡單方法是使用 useContext() 掛鉤。正如你在上面的實際示例中所見,它接受一個引數,並且它必須是一個上下文物件。

這樣,你可以訪問 Provider 元件的 value 屬性並將其儲存在變數中。讓我們再看一個例子:

function Grandchild() {
  const value = useContext(sampleContext)
  return <div className="grandchild" style={{fontSize: 30}}>{value}</div>;
}

value 變數儲存來自自定義 Provider 元件的值。為了更好地演示,請檢視 codesandbox

在 React 中使用 Redux 庫

Redux 是一個用於管理複雜 React 應用程式狀態的庫。它與 React 是分開的,由不同的團隊開發。

Redux 是最受歡迎的庫,是 Context API 的可行替代方案,也是具有豐富功能的更高階庫。它可以替代 Context API。但是,Context API 並不具備 Redux 的所有功能。

Context APIRedux 庫都可以將資料傳遞到樹下部的元件。與 Context API 不同,Redux 帶有 Redux DevTools

Redux DevTools 可以讓你跟蹤你的狀態更新。Redux 還允許你使用 middleware 和許多其他 Context API 不可用的高階功能。

何時使用 Context API 與 React 中的 Redux

如果這是你使用 Redux 的主要動機,你不需要 Redux 將資料共享給子元件而無需手動傳遞 props

如果你考慮改用 Context API,那將是最好的。它具有更簡單的介面,並且更易於設定。

如果使用 middleware 對使你的 React 應用程式正常工作至關重要,那麼 Redux 會更好。Redux 還附帶了額外的庫,例如 redux-persist 用於在本地儲存資料。

要獲取有關 Redux 高階功能的更多資訊,請檢視此部落格

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn