Skip to content

Instantly share code, notes, and snippets.

@cryptiklemur
Created May 16, 2019 16:06
Show Gist options
  • Save cryptiklemur/20e231635a641951e3afc71dd997403b to your computer and use it in GitHub Desktop.
Save cryptiklemur/20e231635a641951e3afc71dd997403b to your computer and use it in GitHub Desktop.
Complex useContext Example (+useReducer)
import {AuthContext} from './AuthContext';
export default ({children}) => (
<AuthContext.AuthProvider initialState={{user: userFromServer}}>
{children}
</AuthContext.AuthProvider>
);
import {createContext, Dispatchm useReducer} from 'react';
import User from '../model/User';
interface State {
user?: User;
specialAwesomeFeature: boolean;
}
type Action =
| {type: 'SET_USER'; user?: User}
| {type: 'SET_FEATURE'; allowed: boolean}
interface Context {
state?: State;
dispatch?: Dispatch<Action>;
}
function reducer(state: State, action: Action) {
switch (action.type) {
case 'SET_USER':
return {...state, user: action.user};
case 'SET_FEATURE':
return {...state, specialAwesomeFeature: action.allowed};
default:
return {...state};
}
}
const initialState: State = {user: null, specialAwesomeFeature: false};
export const AuthContext = createContext<Context>({});
export const AuthProvider = ({children, initialState: overrideInitialState}) => {
const [state, dispatch] = useReducer(reducer, overrideInitialState || initialState);
return <AuthContext.Provider value={{state, dispatch}}>{children}</AuthContext.Provider>;
};
export const setUser = (user?: User): Action => ({type: 'SET_USER', user: user});
import {useContext} from 'react';
import {AuthContext, setUser} from './AuthContext';
export default () => {
const {state, dispatch} = useContext(AuthContext);
return (
<ul>
(state.user && <li onClick={() => dispatch(setUser(null)}}>Log Out</li>}
{!state.user && <li><a href="/login">Log In</a></li>}
{state.specialAwesomeFeature && <li onClick={() => turnOnAwesomeMode()}>Awesome Mode</li>}
</ul>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment