Created
September 5, 2021 09:36
-
-
Save Brenndoerfer/3713aa4ae68209fb2c35875bd1fe5dae to your computer and use it in GitHub Desktop.
Generic Context.Provider for React
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { ReactNode, useReducer } from 'react'; | |
| interface Reducer<T, R extends ActionProps> { | |
| (state: T, action: R): any; | |
| } | |
| interface Dispatch<T extends ActionProps> { | |
| (action: T): void; | |
| } | |
| interface ActionProps { | |
| readonly type: string; | |
| readonly payload?: any; | |
| } | |
| interface Action<T extends ActionProps> { | |
| (dispatch: Dispatch<T>): ( | |
| arg1?: any, | |
| arg2?: any, | |
| arg3?: any, | |
| callback?: any | |
| ) => void; | |
| } | |
| interface Actions<S extends ActionProps> { | |
| [propName: string]: Action<S>; | |
| } | |
| function createDataContext<T, R, S extends ActionProps>( | |
| reducer: Reducer<R, S>, | |
| actions: Actions<S>, | |
| initialState: R | |
| ) { | |
| const Context = React.createContext<T>({} as T); | |
| const Provider = ({ children }: { children: ReactNode }) => { | |
| const [state, dispatch] = useReducer(reducer, initialState); | |
| // actions === { addBlogPost: (dispatch) => { return () => {} }} | |
| const boundActions = {} as any; | |
| for (let key in actions) { | |
| boundActions[key] = actions[key](dispatch); | |
| } | |
| return ( | |
| <Context.Provider value={{ state, ...boundActions }}> | |
| {children} | |
| </Context.Provider> | |
| ); | |
| }; | |
| return { Context, Provider }; | |
| } | |
| export default createDataContext; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment