Skip to content

Commit

Permalink
Add tentative SSR support for useSelector
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Dec 22, 2021
1 parent ce83bf8 commit bc4569f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/components/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface ReactReduxContextValue<
> {
store: Store<SS, A>
subscription: Subscription
getServerState?: () => SS
}

export const ReactReduxContext =
Expand Down
16 changes: 12 additions & 4 deletions src/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,40 @@ import { createSubscription } from '../utils/Subscription'
import { useIsomorphicLayoutEffect } from '../utils/useIsomorphicLayoutEffect'
import { Action, AnyAction, Store } from 'redux'

export interface ProviderProps<A extends Action = AnyAction> {
export interface ProviderProps<A extends Action = AnyAction, S = any> {
/**
* The single Redux store in your application.
*/
store: Store<any, A>
store: Store<S, A>

/**
* An optional server state snapshot. Will be used during initial hydration render if available, to ensure that the UI output is consistent with the HTML generated on the server.
*/
serverState?: S

/**
* Optional context to be used internally in react-redux. Use React.createContext() to create a context to be used.
* If this is used, you'll need to customize `connect` by supplying the same context provided to the Provider.
* Initial value doesn't matter, as it is overwritten with the internal state of Provider.
*/
context?: Context<ReactReduxContextValue<any, A>>
context?: Context<ReactReduxContextValue<S, A>>
children: ReactNode
}

function Provider<A extends Action = AnyAction>({
store,
context,
children,
serverState,
}: ProviderProps<A>) {
const contextValue = useMemo(() => {
const subscription = createSubscription(store)
return {
store,
subscription,
getServerState: serverState ? () => serverState : undefined,
}
}, [store])
}, [store, serverState])

const previousState = useMemo(() => store.getState(), [store])

Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ export function createSelectorHook(
}
}

const { store } = useReduxContext()!
const { store, getServerState } = useReduxContext()!

const selectedState = useSyncExternalStoreWithSelector(
store.subscribe,
store.getState,
// TODO Need a server-side snapshot here
store.getState,
getServerState || store.getState,
selector,
equalityFn
)
Expand Down

0 comments on commit bc4569f

Please sign in to comment.