Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function Provider<A extends Action<string> = UnknownAction, S = unknown>(
const baseContextValue = {
store,
subscription,
getServerState: serverState ? () => serverState : undefined,
getServerState: serverState != null ? () => serverState : undefined,
}

if (process.env.NODE_ENV === 'production') {
Expand Down
2 changes: 1 addition & 1 deletion src/components/connect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
64 changes: 36 additions & 28 deletions test/components/connect.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Passthrough />
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 <Passthrough />
}
}
}

const context = React.createContext<ReactReduxContextValue<
any,
AnyAction
> | null>(null)
const context = React.createContext<ReactReduxContextValue<
any,
AnyAction
> | 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(
<ProviderMock context={context} store={store1}>
<ProviderMock store={store2}>
<Decorated context={context} />
</ProviderMock>
</ProviderMock>,
)
const store1 = createStore(() => expectedState)
const store2 = createStore(() => ignoredState)
rtl.render(
<ProviderMock context={context} store={store1}>
<ProviderMock store={store2}>
<Decorated context={context} />
</ProviderMock>
</ProviderMock>,
)

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 {
Expand Down
38 changes: 38 additions & 0 deletions test/integration/ssr.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <span>{String(useSelector((state: unknown) => state))}</span>
}

const markup = renderToString(
<Provider store={store} serverState={serverState}>
<Value />
</Provider>,
)

expect(markup).toBe(`<span>${String(serverState)}</span>`)
},
)

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 <span>{String(useSelector((state: unknown) => state))}</span>
}

const markup = renderToString(
<Provider store={store} serverState={serverState}>
<Value />
</Provider>,
)

expect(markup).toBe('<span>client</span>')
},
)

it('Handles hydration correctly', async () => {
const ssrStore = createStore(dataSlice.reducer)

Expand Down
Loading