-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for context overwriting
- Loading branch information
1 parent
a790f5f
commit f9c07f6
Showing
8 changed files
with
171 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import {inject} from "vue"; | ||
import type {InjectionKey} from "vue"; | ||
import {ContextKey, VueReduxContextValue} from "../provider/context"; | ||
|
||
/** | ||
* Composition factory, which creates a `useReduxContext` hook bound to a given context. This is a low-level | ||
* composition that you should usually not need to call directly. | ||
* | ||
* @param {InjectionKey<VueReduxContextValue | null>} [context=ContextKey] Context passed to your `provide`. | ||
* @returns {Function} A `useReduxContext` composition bound to the specified context. | ||
*/ | ||
export function createReduxContextComposition(context = ContextKey) { | ||
return function useReduxContext(): VueReduxContextValue { | ||
const contextValue = inject(context) | ||
|
||
if (process.env.NODE_ENV !== 'production' && !contextValue) { | ||
throw new Error( | ||
'could not find react-redux context value; please ensure the component is wrapped in a <Provider>', | ||
) | ||
} | ||
|
||
return contextValue! | ||
} | ||
} | ||
|
||
/** | ||
* A composition to access the value of the `VueReduxContext`. This is a low-level | ||
* composition that you should usually not need to call directly. | ||
* | ||
* @returns {any} the value of the `VueReduxContext` | ||
* | ||
* @example | ||
* | ||
* import { useReduxContext } from '@reduxjs/vue-redux' | ||
* | ||
* export const CounterComponent = () => { | ||
* const { store } = useReduxContext() | ||
* return <div>{store.getState()}</div> | ||
* } | ||
*/ | ||
export const useReduxContext = /*#__PURE__*/ createReduxContextComposition() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from './provide-store' | ||
export * from './use-store' | ||
export * from './use-dispatch' | ||
export * from './use-selector' | ||
export * from './provider/provider' | ||
export * from './provider/context' | ||
export * from './compositions/use-store' | ||
export * from './compositions/use-dispatch' | ||
export * from './compositions/use-selector' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import type { Action, Store, UnknownAction } from 'redux' | ||
import {Subscription} from '../utils/Subscription' | ||
import type { ProviderProps } from './Provider' | ||
import {InjectionKey} from "vue"; | ||
|
||
export interface VueReduxContextValue< | ||
SS = any, | ||
A extends Action<string> = UnknownAction, | ||
> extends Pick<ProviderProps, 'stabilityCheck' | 'identityFunctionCheck'> { | ||
store: Store<SS, A> | ||
subscription: Subscription | ||
} | ||
|
||
export const ContextKey = Symbol.for(`react-redux-context`) as InjectionKey<VueReduxContextValue> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { onScopeDispose, provide } from 'vue' | ||
import type { App, InjectionKey } from 'vue' | ||
import type {Action, Store, UnknownAction} from 'redux' | ||
import {ContextKey, ProviderProps, VueReduxContextValue} from "./context"; | ||
import {createSubscription, Subscription} from "../utils/Subscription"; | ||
|
||
export interface ProviderProps< | ||
A extends Action<string> = UnknownAction, | ||
S = unknown, | ||
> { | ||
/** | ||
* The single Redux store in your application. | ||
*/ | ||
store: Store<S, A> | ||
/** | ||
* Optional context to be used internally in vue-redux. Use `Symbol() as InjectionKey<VueReduxContextValue<S, A>>` to create a context to be used. | ||
* Set the initial value to null, and the compositions will error | ||
* if this is not overwritten by `provide`. | ||
* | ||
* @see https://vuejs.org/guide/typescript/composition-api#typing-provide-inject | ||
*/ | ||
context?: InjectionKey<VueReduxContextValue<S, A> | null> | ||
} | ||
|
||
|
||
export function getContext< | ||
A extends Action<string> = UnknownAction, | ||
S = unknown, | ||
>({ store }: Pick<ProviderProps<A, S>, "store">): VueReduxContextValue<S, A> | null { | ||
const subscription = createSubscription(store) as Subscription | ||
subscription.onStateChange = subscription.notifyNestedSubs | ||
subscription.trySubscribe() | ||
|
||
return { | ||
store, | ||
subscription, | ||
} | ||
} | ||
|
||
export function provideStore< | ||
A extends Action<string> = UnknownAction, | ||
S = unknown, | ||
>({store, context}: ProviderProps<A, S>) { | ||
const contextValue = getContext({store}) | ||
|
||
onScopeDispose(() => { | ||
contextValue.subscription.tryUnsubscribe() | ||
contextValue.subscription.onStateChange = undefined | ||
}) | ||
|
||
const providerKey = context || ContextKey; | ||
|
||
provide(providerKey, contextValue) | ||
} | ||
|
||
export function provideStoreToApp< | ||
A extends Action<string> = UnknownAction, | ||
S = unknown, | ||
>(app: App, {store, context}: ProviderProps<A, S>) { | ||
const contextValue = getContext({store}) | ||
|
||
const providerKey = context || ContextKey; | ||
|
||
app.provide(providerKey, contextValue) | ||
} |