本文へ移動

Provider

概要

<Provider> コンポーネントは、Redux の store を、Redux ストアにアクセスする必要がある入れ子になったコンポーネントに利用可能にします。

React Redux アプリケーション内の任意の React コンポーネントをストアに接続できるため、ほとんどのアプリケーションでは、アプリケーション全体のコンポーネントツリーをその内部に配置して、最上位レベルで <Provider> をレンダリングします。

Hooksconnect API は、React のコンテキストメカニズムを介して、提供されたストアインスタンスにアクセスできます。

プロパティ

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}> を渡すだけで済みます。

コンテキストインスタンスを提供できます。その場合、接続されたすべてのコンポーネントにも同じコンテキストインスタンスを提供する必要があります。適切なコンテキストを提供しないと、このランタイムエラーが発生します。

不変違反

「Connect(MyComponent)」のコンテキストで「store」が見つかりません。ルートコンポーネントを<Provider>でラップするか、カスタムReactコンテキストプロバイダーを<Provider>に、対応するReactコンテキストコンシューマーをconnectオプションのConnect(Todo)に渡してください。

React 18 SSR の使用方法

React-Redux v8 以降、<Provider> は、SSR ハイドレーションシナリオで使用するための serverState プロパティを受け入れます。これは、ハイドレーションの不一致を回避するために hydrateRoot を呼び出している場合に必要です。

サーバーからのシリアライズされた状態全体を serverState プロパティとして渡すと、React はこの状態を初期ハイドレーションレンダリングに使用します。その後、設定プロセス中にクライアント側で発生した変更からの更新を適用します。

基本的な使用方法

以下の例では、<App /> コンポーネントはルートレベルのコンポーネントです。つまり、コンポーネント階層の最上位にあります。

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 ハイドレーション

この例では、クライアントはサーバーによってレンダリングされた HTML と、window に添付されたシリアライズされた Redux 状態を受け取っています。シリアライズされた状態は、ストアの内容を事前に埋めると共に、<Provider>serverState プロパティとして渡されます。

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>,
)