diff --git a/src/components/Provider.tsx b/src/components/Provider.tsx index 5f532c459..aeb385fa7 100644 --- a/src/components/Provider.tsx +++ b/src/components/Provider.tsx @@ -65,7 +65,7 @@ function Provider = UnknownAction, S = unknown>( const baseContextValue = { store, subscription, - getServerState: serverState ? () => serverState : undefined, + getServerState: serverState != null ? () => serverState : undefined, } if (process.env.NODE_ENV === 'production') { diff --git a/src/components/connect.tsx b/src/components/connect.tsx index 3e6c92c39..482ab8633 100644 --- a/src/components/connect.tsx +++ b/src/components/connect.tsx @@ -758,8 +758,8 @@ function _connect< 'You must pass a valid React context consumer as `props.context`', ) } - ResultContext = propsContext } + ResultContext = propsContext } return ResultContext }, [propsContext, Context]) diff --git a/test/components/connect.spec.tsx b/test/components/connect.spec.tsx index 22eac6914..6947da179 100644 --- a/test/components/connect.spec.tsx +++ b/test/components/connect.spec.tsx @@ -2236,41 +2236,49 @@ describe('React', () => { expect(actualState).toEqual(expectedState) }) - it('should use a custom context provider and consumer if passed as a prop to the component', () => { - class Container extends Component { - render() { - return + it.for(['development', 'production'] as const)( + 'should use a custom context prop in %s', + (nodeEnv, { onTestFinished }) => { + vi.stubEnv('NODE_ENV', nodeEnv) + onTestFinished(() => { + vi.unstubAllEnvs() + }) + + class Container extends Component { + render() { + return + } } - } - const context = React.createContext | null>(null) + const context = React.createContext | null>(null) - let actualState + let actualState - const expectedState = { foos: {} } - const ignoredState = { bars: {} } + const expectedState = { foos: {} } + const ignoredState = { bars: {} } - const decorator = connect((state) => { - actualState = state - return { a: 42 } - }) - const Decorated = decorator(Container) + const decorator = connect((state) => { + actualState = state + return { a: 42 } + }) + const Decorated = decorator(Container) - const store1 = createStore(() => expectedState) - const store2 = createStore(() => ignoredState) - rtl.render( - - - - - , - ) + const store1 = createStore(() => expectedState) + const store2 = createStore(() => ignoredState) + rtl.render( + + + + + , + ) - expect(actualState).toEqual(expectedState) - }) + expect(actualState).toEqual(expectedState) + }, + ) it('should ignore non-react-context values that are passed as a prop to the component', () => { class Container extends Component { diff --git a/test/integration/ssr.spec.tsx b/test/integration/ssr.spec.tsx index 1869b5b6d..dfee4b06d 100644 --- a/test/integration/ssr.spec.tsx +++ b/test/integration/ssr.spec.tsx @@ -124,6 +124,44 @@ describe('New v8 serverState behavior', () => { vi.restoreAllMocks() }) + it.for([0, false, ''] as const)( + 'uses a falsy serverState value of %s', + (serverState) => { + const store = createStore((state: unknown = 'client') => state) + + function Value() { + return {String(useSelector((state: unknown) => state))} + } + + const markup = renderToString( + + + , + ) + + expect(markup).toBe(`${String(serverState)}`) + }, + ) + + it.for([null, undefined] as const)( + 'falls back to the store state when serverState is %s', + (serverState) => { + const store = createStore((state: unknown = 'client') => state) + + function Value() { + return {String(useSelector((state: unknown) => state))} + } + + const markup = renderToString( + + + , + ) + + expect(markup).toBe('client') + }, + ) + it('Handles hydration correctly', async () => { const ssrStore = createStore(dataSlice.reducer)