Skip to content

Instantly share code, notes, and snippets.

@it-one-mm
Created June 23, 2020 17:06
Show Gist options
  • Save it-one-mm/674e27cc62d9499f0684b67a95c85c90 to your computer and use it in GitHub Desktop.
Save it-one-mm/674e27cc62d9499f0684b67a95c85c90 to your computer and use it in GitHub Desktop.
Create Global Context
import React, { Dispatch, useReducer, createContext, ReactNode } from 'react';
type Props = {
children: ReactNode;
};
function createDataContext<S, A>(
reducer: (state: S, action: A) => S,
initialState: S
) {
const StateContext = createContext<S | undefined>(undefined);
const DispatchContext = createContext<Dispatch<A> | undefined>(undefined);
function Provider({ children }: Props) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StateContext.Provider value={state}>
<DispatchContext.Provider value={dispatch}>
{children}
</DispatchContext.Provider>
</StateContext.Provider>
);
}
return { StateContext, DispatchContext, Provider };
}
export default createDataContext;
import createDataContext from './createDataContext';
import { Dispatch, useContext } from 'react';
type PhoneModel = {
id?: number;
name: string;
vendorName: string;
logoUrl: string;
createdAt: string;
updatedAt: string;
};
type PhoneModelState = {
data: PhoneModel[];
isLoading?: boolean;
error?: string;
};
const initialState: PhoneModelState = {
data: [],
isLoading: false,
error: '',
};
type PhoneModelAction =
| {
type: 'create_phone_model';
payload: PhoneModel;
}
| { type: 'delete_phone_model' };
const reducer = (state: PhoneModelState, action: PhoneModelAction) => {
switch (action.type) {
case 'create_phone_model':
return { ...state, data: [...state.data, action.payload] };
default:
return state;
}
};
const createPhoneModel = (
dispatch: Dispatch<PhoneModelAction>,
name: string,
logo?: any
) => {
const result: PhoneModel = {
id: 4,
vendorName: 'Xiaomi',
name,
logoUrl: 'Url',
createdAt: '1 second ago',
updatedAt: '1 second ago',
};
dispatch({
type: 'create_phone_model',
payload: result,
});
};
const deletePhoneModel = (dispatch: Dispatch<PhoneModelAction>) => {};
const { StateContext, DispatchContext, Provider } = createDataContext<
PhoneModelState,
PhoneModelAction
>(reducer, initialState);
const usePhoneModel = (): [PhoneModelState, Dispatch<PhoneModelAction>] => {
const state = useContext(StateContext);
const dispatch = useContext(DispatchContext);
if (state === undefined || dispatch === undefined) {
throw new Error('usePhoneModel must be used within a PhoneModelProvider');
}
return [state, dispatch];
};
export {
Provider as PhoneModelProvider,
usePhoneModel,
createPhoneModel,
deletePhoneModel,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment