Skip to content

Instantly share code, notes, and snippets.

@jacobdam
Last active April 24, 2020 10:32
Show Gist options
  • Save jacobdam/fb292105ba6297a1ee09e57b6076361c to your computer and use it in GitHub Desktop.
Save jacobdam/fb292105ba6297a1ee09e57b6076361c to your computer and use it in GitHub Desktop.
class AuthService extends EventEmitter {
async initialize(){
this.accessToken = res['access_token'];
this._checkTokenExpiration();
// ...
}
isSignedIn(){
return !!this.accessToken;
}
async signIn(username, password){
const res = await axios.post('...');
this.accessToken = res['access_token'];
localStorage.set('access_token', res['access_token']);
this.emit('stateChanged');
}
signOut(username, password){}
getAccessToken(){}
getAxios(){
return axios.create(...);
}
// ...
}
const AuthContext = React.createContext();
const AuthProvider = ({children}) => {
const authServiceRef = useRef();
const [initialized, setInitialized] = useState(false);
useEffect({} => {
authServiceRef.current = new AuthService();
authServiceRef.current.initialize().then(() => {
setInitialized(true);
});
}, []);
if (!initialized) {
return <LoadingPage />; // or just return null
}
const authService = authServiceRef.current;
return (
<AuthContext.Provider value={{ authService }}>
{children}
</AuthContext.Provider>
);
}
const useAuthService = () => {
const value = useContext(AuthContext);
invariant(value !== undefined, 'useAuthService must be called inside AuthProvider block');
return value;
}
const useAxios = () => {
const authService = useAuthService();
const [axios, setAxios] = useState(() => { authService.getAxios(); });
useEffect(() => {
const stateChangedHandler = () => {
setAxios(authService.getAxios());
};
authService.on('stateChanged', stateChangedHandler);
return () => {
authService.removeListener('stateChanged', stateChangedHandler)
};
});
return axios;
}
// App.js
const App = () => (
<AuthProvider>
<Routes />
</AuthProvider>
);
// Card.js
const Cart = () => {
const axios = useAxios();
useEffect(() => {
axios.get(...);
});
return (...);
}
const AuthContext = React.createContext();
class AuthProvider extend Component {
constructor() {
this.authService = null;
this.state = {
initialized: false
};
}
componentDidMount() {
this.authService = new AuthService();
this.authService.initialize().then(() => {
setState({ initialized: true });
});
}
render() {
const { initialized } = this.state;
if (!initialized) {
return <Loading/>; // or return null
}
return (
<AuthContext.Provider value={{ this.authService }}>
{children}
</AuthContext.Provider>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment