You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
46 lines
1.4 KiB
46 lines
1.4 KiB
5 days ago
|
import { createContext, Dispatch, ReactNode, useContext, useReducer } from 'react';
|
||
|
|
||
|
type State = { count: number };
|
||
|
type Action = { type: 'INCREMENT' | 'DECREMENT' };
|
||
|
|
||
|
const initialState: State = { count: 0 };
|
||
|
|
||
|
function counterReducer(state: State, action: Action): State {
|
||
|
switch (action.type) {
|
||
|
case 'INCREMENT':
|
||
|
return { count: state.count + 1 };
|
||
|
case 'DECREMENT':
|
||
|
return { count: state.count - 1 };
|
||
|
default:
|
||
|
throw new Error('Unhandled action');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const CounterStateContext = createContext<State | undefined>(undefined);
|
||
|
const CounterDispatchContext = createContext<Dispatch<Action> | undefined>(undefined);
|
||
|
|
||
|
export function CounterProvider({ children }: { children: ReactNode }) {
|
||
|
const [state, dispatch] = useReducer(counterReducer, initialState);
|
||
|
return (
|
||
|
<CounterStateContext.Provider value={state}>
|
||
|
<CounterDispatchContext.Provider value={dispatch}>{children}</CounterDispatchContext.Provider>
|
||
|
</CounterStateContext.Provider>
|
||
|
);
|
||
|
}
|
||
|
|
||
|
export function useCounterState() {
|
||
|
const context = useContext(CounterStateContext);
|
||
|
if (context === undefined)
|
||
|
throw new Error('useCounterState must be used within a CounterProvider');
|
||
|
|
||
|
return context;
|
||
|
}
|
||
|
|
||
|
export function useCounterDispatch() {
|
||
|
const context = useContext(CounterDispatchContext);
|
||
|
if (context === undefined)
|
||
|
throw new Error('useCounterDispatch must be used within a CounterProvider');
|
||
|
|
||
|
return context;
|
||
|
}
|