Skip to content

Instantly share code, notes, and snippets.

@rpCal
Last active April 29, 2020 08:42
Show Gist options
  • Save rpCal/4a58ff9b14dc777ba09bcd99a7ca362d to your computer and use it in GitHub Desktop.
Save rpCal/4a58ff9b14dc777ba09bcd99a7ca362d to your computer and use it in GitHub Desktop.
typescript/react/immerjs - React.useReducer + hooks
import React from "react";
import { produce } from "immer";
export interface ModalForm {
id: string | undefined;
}
export const initModalForm: ModalForm = {
id: undefined,
};
type Action = { type: "setName"; payload: string };
type Dispatch = (action: Action) => void;
type State = {
modalForm: ModalForm;
};
type ContextProviderProps = { children: React.ReactNode };
export const initalState: State = {
modalForm: { ...initModalForm },
};
const StateContext = React.createContext<State | undefined>(undefined);
const DispatchContext = React.createContext<Dispatch | undefined>(undefined);
function reducer(state: State, action: Action): State {
console.log("reducer: log", state, action.type, action.payload);
switch (action.type) {
case "setName": {
return produce(state, (draft) => {
draft.modalForm.id = action.payload;
});
}
default: {
throw new Error(`Unhandled action type: ${(action as any).toString()}`);
}
}
}
function ContextProvider({ children }: ContextProviderProps) {
const [state, dispatch] = React.useReducer(reducer as any, initalState);
return (
<StateContext.Provider value={state as any}>
<DispatchContext.Provider value={dispatch as Dispatch}>
{children}
</DispatchContext.Provider>
</StateContext.Provider>
);
}
function useContextState() {
const context = React.useContext(StateContext);
if (context === undefined) {
throw new Error("useContextState must be used within a Provider");
}
return context;
}
function useContextDispatch() {
const context = React.useContext(DispatchContext);
if (context === undefined) {
throw new Error("useContextDispatch must be used within a Provider");
}
return context;
}
export { ContextProvider, useContextState, useContextDispatch };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment