UNPKG

2.11 kBTypeScriptView Raw
1import { configureStore } from '@reduxjs/toolkit'
2import type { Context } from 'react'
3import { useContext } from 'react'
4import { useEffect } from 'react'
5import React from 'react'
6import type { ReactReduxContextValue } from 'react-redux'
7import { Provider, ReactReduxContext } from 'react-redux'
8import { setupListeners } from '@reduxjs/toolkit/query'
9import type { Api } from '@reduxjs/toolkit/query'
10
11/**
12 * Can be used as a `Provider` if you **do not already have a Redux store**.
13 *
14 * @example
15 * ```tsx
16 * // codeblock-meta no-transpile title="Basic usage - wrap your App with ApiProvider"
17 * import * as React from 'react';
18 * import { ApiProvider } from '@reduxjs/toolkit/query/react';
19 * import { Pokemon } from './features/Pokemon';
20 *
21 * function App() {
22 * return (
23 * <ApiProvider api={api}>
24 * <Pokemon />
25 * </ApiProvider>
26 * );
27 * }
28 * ```
29 *
30 * @remarks
31 * Using this together with an existing redux store, both will
32 * conflict with each other - please use the traditional redux setup
33 * in that case.
34 */
35export function ApiProvider(props: {
36 children: any
37 api: Api<any, {}, any, any>
38 setupListeners?: Parameters<typeof setupListeners>[1] | false
39 context?: Context<ReactReduxContextValue | null>
40}) {
41 const context = props.context || ReactReduxContext
42 const existingContext = useContext(context)
43 if (existingContext) {
44 throw new Error(
45 'Existing Redux context detected. If you already have a store set up, please use the traditional Redux setup.',
46 )
47 }
48 const [store] = React.useState(() =>
49 configureStore({
50 reducer: {
51 [props.api.reducerPath]: props.api.reducer,
52 },
53 middleware: (gDM) => gDM().concat(props.api.middleware),
54 }),
55 )
56 // Adds the event listeners for online/offline/focus/etc
57 useEffect(
58 (): undefined | (() => void) =>
59 props.setupListeners === false
60 ? undefined
61 : setupListeners(store.dispatch, props.setupListeners),
62 [props.setupListeners, store.dispatch],
63 )
64
65 return (
66 <Provider store={store} context={context}>
67 {props.children}
68 </Provider>
69 )
70}