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.
 
 

55 lines
1.4 KiB

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