Skip to main content

Context

Context API

The Context API comes in handy when we want to move state or make it easy accessible to distant children. A context can not only contain state but also actions that help us to mutate that state. We can easily combine the Context API with useReducer to dispatch actions that we pull in from a certain context in screens.

Automate Context Creation

To automate the creation of a context and action it provides you can use the following boilerplate code (createDataContext.tsx):

import React, {createContext, useReducer} from 'react';

export interface Action {
type: string,
payload: any
}

export default (reducer: any, actions: any, initialState: any) => {
const Context = createContext({} as any);

const Provider = ({children}: { children: any }) => {
const [state, dispatch] = useReducer(reducer, initialState);

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

Usage

In a context, e.g. AuthContext.ts, all you need is to create the reducer, the actions and call the function from above and export the context and provider.

const authReducer = (state: any, action: Action) => {
switch (action.type) {
case 'signin':
return {errorMessage: '', token: action.payload};
default:
return state;
}
};

const signIn = (dispatch: any) => async ({email, password}) => {
const response = await authApi.post('/signin', {email, password});
dispatch({type: 'signin', payload: response});
};

export const {Context, Provider} = createDataContext(
authReducer, // reducer
{signIn}, // actions
{} // initial state
);

Provide inApp.tsx:

import { Provider as AuthProvider } from "./src/context/AuthContext";

const App = createAppContainer(...);

export default () => {
return (
<AuthProvider>
<App/>
</AuthProvider>
);
}

Consume in any screen:

import {Context as AuthContext} from '../context/AuthContext';

const {state, sigin} = useContext(AuthContext);