Best way for generic store + React context #2432
Unanswered
jeanbenoit-richez
asked this question in
Q&A
Replies: 2 comments 7 replies
-
Hey, |
Beta Was this translation helpful? Give feedback.
7 replies
-
import { createContext, useContext, useRef, type PropsWithChildren } from 'react'
import { useStore, createStore } from 'zustand'
type Chain = {}
type ChainSelectConfig<T> = {}
type ConnectorsMap = {}
const environment: any = {}
const CHAINS: any = {}
const ChainsID: any = {}
export type RealtokenProviderSetableProps<T extends Partial<Chain>> = {
showAllNetworks?: boolean;
chainConfig: ChainSelectConfig<T>;
env?: string;
}
type RealtokenProviderFixedProps = {
setShowAllNetworks: (state: boolean) => void,
storeLoaded: boolean,
setStoreLoaded: (state: boolean) => void,
connectors: ConnectorsMap | undefined;
setConnectors: (connectors: ConnectorsMap) => void;
};
export type RealtokenStoreProps<T extends Partial<Chain>> = RealtokenProviderSetableProps<T> & RealtokenProviderFixedProps;
export type RealtokenStore<T extends Partial<Chain>> = ReturnType<typeof createRealtStore<T>>;
function createRealtStore<T extends Partial<Chain>>(initProps?: Partial<RealtokenProviderSetableProps<T>>) {
const DEFAULT_PROPS: RealtokenProviderSetableProps<T> = {
env: environment.PRODUCTION,
showAllNetworks: false,
chainConfig: {
allowedChains: parseAllowedChain(ChainsID),
chainsConfig: CHAINS,
defaultChainId: ChainsID.Gnosis
} as ChainSelectConfig<T>
}
return createStore<RealtokenStoreProps<T>>((set) => ({
...DEFAULT_PROPS,
...initProps,
showAllNetworks: false,
setShowAllNetworks: (showAllNetworks: boolean) => set({ showAllNetworks }),
storeLoaded: false,
setStoreLoaded: (storeLoaded: boolean) => set({ storeLoaded }),
env: environment.PRODUCTION,
connectors: undefined,
setConnectors: (connectors: ConnectorsMap) => set({ connectors }),
}));
}
export function getRealtokenProviderContext<T extends Partial<Chain>>() {
return createContext<RealtokenStore<T> | null>(null)
}
interface RealtokenProviderProps<T extends Partial<Chain>> extends PropsWithChildren {
value: RealtokenProviderSetableProps<T>
}
type Selector<T, U> = (state: T) => U
export function useRealtokenStore<T extends Partial<Chain>, U>(selector: Selector<RealtokenStoreProps<T>, U>): U {
const store = useContext(getRealtokenProviderContext<T>())
if (!store) throw new Error('Missing RealtokenProviderContext.Provider in the tree')
return useStore(store, selector)
}
export function RealtokenProvider<T extends Partial<Chain>>({ children, value }: RealtokenProviderProps<T>) {
const storeRef = useRef<RealtokenStore<T>>()
if (!storeRef.current) {
storeRef.current = createRealtStore<T>(value)
}
const RealtokenProviderContext = getRealtokenProviderContext<T>();
return (
<RealtokenProviderContext.Provider value={storeRef.current}>
{children}
</RealtokenProviderContext.Provider>
)
}
const SomeComponent = () => {
const state = useRealtokenStore(state => state)
return null
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi,
I created a store where one of props is generic:
And a custom mock store hook:
When i'm trying to use my store's hook:
It works well but I cant' used it whiteout passing both of the generic type: T and U.
Is there anyway to avoid this ? And have the same behaviour then the basic hook: the return type is deducted by typescript.
Thank you for help 🙏🏻
Beta Was this translation helpful? Give feedback.
All reactions