Skip to content

Instantly share code, notes, and snippets.

@diego3g
Created April 21, 2020 16:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save diego3g/b0b0c6fe892e2e0fa714b606d4262246 to your computer and use it in GitHub Desktop.
Save diego3g/b0b0c6fe892e2e0fa714b606d4262246 to your computer and use it in GitHub Desktop.
import React, {
createContext,
useState,
useCallback,
useContext,
useEffect,
} from 'react';
import AsyncStorage, {
useAsyncStorage,
} from '@react-native-community/async-storage';
import api from '../utils/apiClient';
interface AuthState {
token?: string;
user?: object;
}
interface SignInCredentials {
email: string;
password: string;
}
interface AuthContext {
user?: object;
loading: boolean;
signIn(credentials: SignInCredentials): Promise<void>;
signOut(): void;
}
const AuthContext = createContext<AuthContext | null>(null);
const AuthProvider: React.FC = ({ children }) => {
const storagedToken = useAsyncStorage('@GoBarber:token');
const storagedUser = useAsyncStorage('@GoBarber:user');
const [data, setData] = useState<AuthState>({});
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadUserAndToken(): Promise<void> {
const token = await storagedToken.getItem();
const user = await storagedUser.getItem();
if (token && user) {
setData({ token, user: JSON.parse(user) });
}
setLoading(false);
}
loadUserAndToken();
}, [storagedToken, storagedUser]);
const signIn = useCallback(
async credentials => {
const response = await api.post('sessions', credentials);
const { token, user } = response.data;
await storagedToken.setItem(token);
await storagedUser.setItem(JSON.stringify(user));
setData({ token, user });
},
[storagedToken, storagedUser],
);
const signOut = useCallback(async () => {
await AsyncStorage.clear();
setData({});
}, []);
const user = data?.user;
const value = React.useMemo(() => ({ loading, user, signIn, signOut }), [
loading,
signIn,
signOut,
user,
]);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};
function useAuth(): AuthContext {
const context = useContext(AuthContext);
if (!context) {
throw new Error(`useAuth must be used within a AuthProvider`);
}
return context;
}
export { AuthProvider, useAuth };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment