import { configureStore } from '@reduxjs/toolkit' import type { Context } from 'react' import { useContext } from 'react' import { useEffect } from 'react' import React from 'react' import type { ReactReduxContextValue } from 'react-redux' import { Provider, ReactReduxContext } from 'react-redux' import { setupListeners } from '@reduxjs/toolkit/query' import type { Api } from '@reduxjs/toolkit/query' /** * Can be used as a `Provider` if you **do not already have a Redux store**. * * @example * ```tsx * // codeblock-meta no-transpile title="Basic usage - wrap your App with ApiProvider" * import * as React from 'react'; * import { ApiProvider } from '@reduxjs/toolkit/query/react'; * import { Pokemon } from './features/Pokemon'; * * function App() { * return ( * * * * ); * } * ``` * * @remarks * Using this together with an existing redux store, both will * conflict with each other - please use the traditional redux setup * in that case. */ export function ApiProvider(props: { children: any api: Api setupListeners?: Parameters[1] | false context?: Context }) { const context = props.context || ReactReduxContext const existingContext = useContext(context) if (existingContext) { throw new Error( 'Existing Redux context detected. If you already have a store set up, please use the traditional Redux setup.', ) } const [store] = React.useState(() => configureStore({ reducer: { [props.api.reducerPath]: props.api.reducer, }, middleware: (gDM) => gDM().concat(props.api.middleware), }), ) // Adds the event listeners for online/offline/focus/etc useEffect( (): undefined | (() => void) => props.setupListeners === false ? undefined : setupListeners(store.dispatch, props.setupListeners), [props.setupListeners, store.dispatch], ) return ( {props.children} ) }