Skip to content

Instantly share code, notes, and snippets.

@alanfoandrade
Created September 30, 2020 03:08
Show Gist options
  • Save alanfoandrade/488f3e200c58175833b25c8bbbd8cbf3 to your computer and use it in GitHub Desktop.
Save alanfoandrade/488f3e200c58175833b25c8bbbd8cbf3 to your computer and use it in GitHub Desktop.
import React, {
useEffect,
createContext,
useCallback,
useState,
useContext,
} from 'react';
import AsyncStorage from '@react-native-community/async-storage';
import api from '../services/api';
interface IUser {
id: string;
name: string;
email: string;
avatar_url: string;
}
interface IAuthState {
token: string;
user: IUser;
}
interface ISignInCredentials {
email: string;
password: string;
}
interface IAuthContextData {
user: IUser;
loading: boolean;
signIn(credentials: ISignInCredentials): Promise<void>;
signOut(): void;
updateUser(user: IUser): Promise<void>;
}
const AuthContext = createContext<IAuthContextData>({} as IAuthContextData);
const AuthProvider: React.FC = ({ children }) => {
const [data, setData] = useState<IAuthState>({} as IAuthState);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadStoragedData(): Promise<void> {
const [token, user] = await AsyncStorage.multiGet([
'@AppName:token',
'@AppName:user',
]);
if (token[1] && user[1]) {
api.defaults.headers.authorization = `Bearer ${token[1]}`;
setData({ token: token[1], user: JSON.parse(user[1]) });
}
setLoading(false);
}
loadStoragedData();
}, []);
const signIn = useCallback(async ({ email, password }) => {
const response = await api.post('sessions', {
email,
password,
});
const { token, user } = response.data;
await AsyncStorage.multiSet([
['@AppName:token', token],
['@AppName:user', JSON.stringify(user)],
]);
api.defaults.headers.authorization = `Bearer ${token}`;
setData({ token, user });
}, []);
const signOut = useCallback(async () => {
await AsyncStorage.multiRemove(['@AppName:token', '@AppName:user']);
setData({} as IAuthState);
}, []);
const updateUser = useCallback(async (user: IUser) => {
AsyncStorage.setItem('@AppName:user', JSON.stringify(user));
setData((prev) => ({
token: prev.token,
user,
}));
}, []);
return (
<AuthContext.Provider
value={{ user: data.user, signIn, signOut, loading, updateUser }}
>
{children}
</AuthContext.Provider>
);
};
function useAuth(): IAuthContextData {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be use within an AuthProvider');
}
return context;
}
export { AuthProvider, useAuth };
import React from 'react';
import { AuthProvider } from './auth';
const AppProvider: React.FC = ({ children }) => (
<AuthProvider>{children}</AuthProvider>
);
export default AppProvider;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment