From f3fd32f965868666d94a9504836b8f282eb34827 Mon Sep 17 00:00:00 2001 From: "ben.durrant" Date: Tue, 7 Nov 2023 12:28:06 +0000 Subject: [PATCH 1/2] Throw an error if ApiProvider is nested inside a normal Provider. --- packages/toolkit/src/query/react/ApiProvider.tsx | 12 ++++++++++-- .../toolkit/src/query/tests/apiProvider.test.tsx | 13 +++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/toolkit/src/query/react/ApiProvider.tsx b/packages/toolkit/src/query/react/ApiProvider.tsx index 5be6ea06ad..4c9f7acf23 100644 --- a/packages/toolkit/src/query/react/ApiProvider.tsx +++ b/packages/toolkit/src/query/react/ApiProvider.tsx @@ -1,9 +1,10 @@ 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 } from 'react-redux' +import { Provider, ReactReduxContext } from 'react-redux' import { setupListeners } from '@reduxjs/toolkit/query' import type { Api } from '@reduxjs/toolkit/query' @@ -37,6 +38,13 @@ export function ApiProvider>(props: { 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: { @@ -55,7 +63,7 @@ export function ApiProvider>(props: { ) return ( - + {props.children} ) diff --git a/packages/toolkit/src/query/tests/apiProvider.test.tsx b/packages/toolkit/src/query/tests/apiProvider.test.tsx index 3da38e1579..98e562cd71 100644 --- a/packages/toolkit/src/query/tests/apiProvider.test.tsx +++ b/packages/toolkit/src/query/tests/apiProvider.test.tsx @@ -2,6 +2,8 @@ import * as React from 'react' import { createApi, ApiProvider } from '@reduxjs/toolkit/query/react' import { fireEvent, render, waitFor } from '@testing-library/react' import { waitMs } from './helpers' +import { Provider } from 'react-redux' +import { configureStore } from '@reduxjs/toolkit' const api = createApi({ baseQuery: async (arg: any) => { @@ -57,4 +59,15 @@ describe('ApiProvider', () => { // Being that nothing has changed in the args, this should never fire. expect(getByTestId('isFetching').textContent).toBe('false') }) + test('ApiProvider throws if nested inside a Redux context', () => { + expect(() => + render( + null })}> + child + + ) + ).toThrowErrorMatchingInlineSnapshot( + '"Existing Redux context detected. If you already have a store set up, please use the traditional Redux setup."' + ) + }) }) From 9ef5ff9963582e928ef8b63a23613c3eb7e1a040 Mon Sep 17 00:00:00 2001 From: Ben Durrant Date: Wed, 8 Nov 2023 12:06:19 +0000 Subject: [PATCH 2/2] update errors.json --- errors.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/errors.json b/errors.json index e6513b5abc..ad527b78d8 100644 --- a/errors.json +++ b/errors.json @@ -31,5 +31,7 @@ "29": "`builder.addCase` cannot be called with an empty action type", "30": "`builder.addCase` cannot be called with two reducers for the same action type", "31": "\"middleware\" field must be a callback", - "32": "When using custom hooks for context, all hooks need to be provided: .\\nHook was either not provided or not a function." -} + "32": "When using custom hooks for context, all hooks need to be provided: .\\nHook was either not provided or not a function.", + "33": "Existing Redux context detected. If you already have a store set up, please use the traditional Redux setup.", + "34": "selectSlice returned undefined for an uninjected slice reducer" +} \ No newline at end of file