Skip to main content

Provider

概述

¥Overview

<Provider> 组件使 Redux store 可用于任何需要访问 Redux 存储的嵌套组件。

¥The <Provider> component makes the Redux store available to any nested components that need to access the Redux store.

由于 React Redux 应用中的任何 React 组件都可以连接到存储,因此大多数应用将在顶层渲染 <Provider>,其中包含整个应用的组件树。

¥Since any React component in a React Redux app can be connected to the store, most applications will render a <Provider> at the top level, with the entire app’s component tree inside of it.

然后,钩子connect API 可以通过 React 的 Context 机制访问提供的存储实例。

¥The Hooks and connect APIs can then access the provided store instance via React's Context mechanism.

属性

¥Props

interface ProviderProps<A extends Action = AnyAction, S = any> {
/**

* The single Redux store in your application.
*/
store: Store<S, A>

/**

* An optional server state snapshot. Will be used during initial hydration render

* if available, to ensure that the UI output is consistent with the HTML generated on the server.

* New in 8.0
*/
serverState?: S

/**

* Optional context to be used internally in react-redux. Use React.createContext()

* to create a context to be used.

* If this is used, you'll need to customize `connect` by supplying the same

* context provided to the Provider.

* Set the initial value to null, and the hooks will error

* if this is not overwritten by Provider.
*/
context?: Context<ReactReduxContextValue<S, A> | null>

/** Global configuration for the `useSelector` stability check */
stabilityCheck?: StabilityCheck

/** The top-level React elements in your component tree, such as `<App />` **/
children: ReactNode
}

通常,你只需要通过 <Provider store={store}> 即可。

¥Typically, you only need to pass <Provider store={store}>.

你可以提供一个上下文实例。如果这样做,你还需要为所有连接的组件提供相同的上下文实例。未能提供正确的上下文会导致此运行时错误:

¥You may provide a context instance. If you do so, you will need to provide the same context instance to all of your connected components as well. Failure to provide the correct context results in this runtime error:

不变违规

¥Invariant Violation

在 "Connect(MyComponent)" 的上下文中找不到 "store"。将根组件封装在 <Provider> 中,或者将自定义 React 上下文提供者传递给 <Provider>,并将相应的 React 上下文使用者传递给连接选项中的 Connect(Todo)。

¥Could not find "store" in the context of "Connect(MyComponent)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Todo) in connect options.

React 18 SSR 用法

¥React 18 SSR Usage

从 React-Redux v8 开始,<Provider> 现在接受 serverState prop 用于 SSR 水合场景。如果你调用 hydrateRoot 以避免水合不匹配,则这是必要的。

¥As of React-Redux v8, <Provider> now accepts a serverState prop for use in SSR hydration scenarios. This is necessary if you are calling hydrateRoot in order to avoid hydration mismatches.

你应该将整个序列化状态作为 serverState 属性从服务器传递,React 将使用此状态进行初始水合渲染。之后,它将应用安装过程中客户端上发生的更改的任何更新。

¥You should pass the entire serialized state from the server as the serverState prop, and React will use this state for the initial hydration render. After that, it will apply any updates from changes that occurred on the client during the setup process.

示例

¥Examples

基本用法

¥Basic Usage

在下面的示例中,<App /> 组件是我们的根级组件。这意味着它位于我们组件层次结构的最顶层。

¥In the example below, the <App /> component is our root-level component. This means it’s at the very top of our component hierarchy.

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'

import { App } from './App'
import createStore from './createReduxStore'

const store = createStore()

// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>,
)

React 18 SSR 水合

¥React 18 SSR Hydration

在此示例中,客户端已收到服务器渲染的 HTML,以及附加到 window 的序列化 Redux 状态。序列化状态用于预填充存储的内容,并作为 serverState 属性传递给 <Provider>

¥In this example, the client has received HTML rendered by the server, as well as a serialized Redux state attached to window. The serialized state is used to both pre-fill the store's contents, and passed as the serverState prop to <Provider>

src/index.ts
import { hydrateRoot } from 'react-dom/client'
import { configureStore } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'

const preloadedState = window.__PRELOADED_STATE__

const clientStore = configureStore({
reducer: rootReducer,
preloadedState,
})

hydrateRoot(
document.getElementById('root'),
<Provider store={clientStore} serverState={preloadedState}>
<App />
</Provider>,
)