跳至主要內容

存取儲存庫

React Redux 提供的 API 可讓您的元件傳送動作並訂閱儲存庫的資料更新。

因此,React Redux 省去了您使用何種儲存庫以及該儲存庫互動的詳細處理的細節。在一般使用情況下,您自己的元件永遠不需要在意這些細節,也不會直接參考儲存庫。React Redux 內部也會處理將儲存庫和狀態傳遞給連接元件的詳細資訊,因此這預設會依預期運作。

不過,在某些使用案例中,您可能需要自訂儲存庫和狀態傳遞給連接元件的方式,或直接存取儲存庫。以下列出一些執行此操作的方式範例。

了解如何使用 Context

在內部,React Redux 使用 React 的「context」功能,讓 Redux 儲存庫可供深入巢狀的連接元件使用。從 React Redux 6 版開始,這通常由 React.createContext() 產生的單一預設 context 物件執行,稱為 ReactReduxContext

React Redux 的 <Provider> 元件使用 <ReactReduxContext.Provider>,將 Redux 儲存庫和目前儲存庫狀態置入 context,而 connect 使用 useContext(ReactReduxContext) 來讀取這些值和處理更新。

使用 useStore 鉤子

useStore 鉤子返回來自預設 ReactReduxContext 的當前儲存體執行個體。如果你真的需要存取儲存體,建議採用這種方法。

提供自訂內容

你可能提供你自己的自訂內容執行個體,而不是使用來自 React Redux 的預設內容執行個體。

<Provider context={MyContext} store={store}>
<App />
</Provider>

如果你提供自訂內容,React Redux 會使用該內容執行個體,而不是預設建立並輸出的內容執行個體。

提供自訂內容到 <Provider /> 後,你會需要提供此內容執行個體到你所有的已連接元件,預期這些元件會連線到相同的儲存體

// You can pass the context as an option to connect
export default connect(
mapState,
mapDispatch,
null,
{ context: MyContext }
)(MyComponent)

// or, call connect as normal to start
const ConnectedComponent = connect(
mapState,
mapDispatch
)(MyComponent)

// Later, pass the custom context as a prop to the connected component
<ConnectedComponent context={MyContext} />

當 React Redux 在它正在尋找的內容中找不到儲存體時,會發生下列執行時期錯誤。例如

  • 你提供自訂內容執行個體到 <Provider />,但沒有提供相同的執行個體(或沒有提供任何執行個體)到你的已連接元件。
  • 你提供自訂內容到你的已連接元件,但沒有提供相同的執行個體(或沒有提供任何執行個體)到 <Provider />

不變式違反

找不到 "儲存體" 於 "Connect(MyComponent)" 的內容中。請用 <Provider> 包住根元件,或傳遞自訂 React 內容提供者到 <Provider>,並將對應的 React 內容消費者傳遞到連接選項的 Connect(Todo)。

自訂內容與鉤子 API

透過鉤子 API 存取自訂內容,你可以使用 鉤子產生函式 建立自訂鉤子。

多個儲存體

Redux 是設計用來使用單一儲存體的。不過,如果你遇到無法避免非得使用多個儲存體的情況,那麼從 v6 起你可以透過提供(多個)自訂內容,來達成這件事。這也能自然地隔離儲存體,因為它們存在於不同的內容執行個體內。

// a naive example
const ContextA = React.createContext(null);
const ContextB = React.createContext(null);

// assuming reducerA and reducerB are proper reducer functions
const storeA = createStore(reducerA);
const storeB = createStore(reducerB);

// supply the context instances to Provider
function App() {
return (
<Provider store={storeA} context={ContextA} />
<Provider store={storeB} context={ContextB}>
<RootModule />
</Provider>
</Provider>
);
}

// fetch the corresponding store with connected components
// you need to use the correct context
connect(mapStateA, null, null, { context: ContextA })(MyComponentA)

// You may also pass the alternate context instance directly to the connected component instead
<ConnectedMyComponentA context={ContextA} />

// it is possible to chain connect()
// in this case MyComponent will receive merged props from both stores
compose(
connect(mapStateA, null, null, { context: ContextA }),
connect(mapStateB, null, null, { context: ContextB })
)(MyComponent);

直接使用 ReactReduxContext

在少數情況下,你可能需要在你自己的元件中直接存取 Redux 儲存體。你可以透過自行呈現適當的內容消費者,並存取該內容值中的 store 欄位,來達成這件事。

小心

並不被視為 React Redux 公開 API 的一部分,並可能在沒有通知的情況下中斷。我們確實認識到社群有必要使用案例,並將嘗試讓使用者能夠在 React Redux 之上建立其他功能,但我們對內容的特定使用被視為實作細節。如果您有其他使用案例未被目前的 API 充分涵蓋,請提交問題以討論可能的 API 改進。

import { ReactReduxContext } from 'react-redux'

// Somewhere inside of a <Provider>
function MyConnectedComponent() {
// Access the store via the `useContext` hook
const { store } = useContext(ReactReduxContext)

// alternately, use the render props form of the context
/*
return (
<ReactReduxContext.Consumer>
{({ store }) => {
// do something useful with the store, like passing it to a child
// component where it can be used in lifecycle methods
}}
</ReactReduxContext.Consumer>
)
*/
}

進一步資源