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

2 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;
}