I made a custom context:
interface IContextProps {
state: StateType;
dispatch: Dispatch<Action>;
}
const Context = React.createContext({} as IContextProps);
export const useCustomContext = (): IContextProps => {
return React.useContext(Context);
};
export default Context;
State type:
export type StateType = {
items: Array<DataItems>;
global: StateTypeGlobal;
};
I had one big reducer which I wanted to split and combine with combineReducer
export const combineReducers = (slices) => (state, action) =>
Object.keys(slices).reduce(
(acc, prop) => ({
...acc,
[prop]: slices[prop](acc[prop], action),
}),
state
);
When I initialize the provider:
const rootReducer = combineReducers({
global: globalReducer,
items: ItemReducer,
});
const [state, dispatch] = React.useReducer(rootReducer, initalState);
const store = React.useMemo(() => [state, dispatch], [state, dispatch]);
<Context.Provider value={store}>
</Context.Provider>
here I get an error saying:
Type 'any[]' is missing the following properties from type 'IContextProps': state, dispatchts(2739) index.d.ts(328, 9): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & ProviderProps'
Which made sense since I am sending in an Array and not an object. This made me change my customContext to:
const Context = React.createContext([] as Array<IContextProps>);
export const useCustomContext = (): Array<IContextProps> => {
return React.useContext(Context);
};
export default Context;
Problem
How do I extract state?
In a file I previosly did:
const { state, dispatch } = useCustomContext();
This worked but now gives me the following error:
Property 'state' does not exist on type 'IContextProps[]'.
Property 'dispatch' does not exist on type 'IContextProps[]'.
EDIT:
This isn't really related to React or context; you're simply mixing up your types.
In the first example, your context's type is an object, but you're passing an array to the Provider
. A simpler example with the same problem:
interface IContextProps {
state: StateType;
dispatch: Dispatch<Action>;
}
const example = (value: IContextProps) => {};
const value: any[] = [state, dispatch];
/*
* Argument of type 'any[]' is not assignable to parameter of type 'IContextProps'.
* Type 'any[]' is missing the following properties from type 'IContextProps':
* state, dispatch ts(2345)
*/
example(value);
Instead of the array in the useMemo
, you want an object that matches the IContextProps
interface, e.g.:
// value is an object
const store = React.useMemo(() => ({ state, dispatch }), [state, dispatch]);
<Context.Provider value={store}>
</Context.Provider>