Created
May 30, 2020 13:24
-
-
Save giacomorebonato/cb2a146278c1bf6a6cfc34ce00fec9d1 to your computer and use it in GitHub Desktop.
useAuth authentication hook for React and Apollo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Auth { | |
user?: UserData | |
login( | |
email: string, | |
password: string | |
): Promise<ExecutionResult<{ login: LOGIN_USER_DATA }>> | |
logout(): Promise<ExecutionResult<any>> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export { AuthProvider } from './useAuth' | |
export { useAuth } from './useAuth' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { gql } from 'apollo-boost' | |
export const MUTATE_LOGOUT = gql` | |
mutation { | |
logout | |
} | |
` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { gql } from 'apollo-boost' | |
export const QUERY_USER = gql` | |
query { | |
me { | |
id | |
} | |
} | |
` | |
export interface QueryUserData { | |
me: UserData | |
} | |
export interface UserData { | |
id: number | |
email: string | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { useQuery, useMutation } from '@apollo/react-hooks' | |
import { LOGIN_USER_DATA, LOGIN_USER } from '../../mutations/LOGIN_USER' | |
import { LOGOUT_USER } from '../../mutations/LOGOUT_USER' | |
import { QUERY_USER, QueryUserData } from './QUERY_USER' | |
import { Box, Spinner, Button, Text } from '@chakra-ui/core' | |
const AuthContext = React.createContext<Auth | null>(null) | |
export const AuthProvider: React.FC = ({ children }) => { | |
const [mutateLogin] = useMutation<{ login: LOGIN_USER_DATA }>(LOGIN_USER) | |
const [mutateLogout] = useMutation(LOGOUT_USER) | |
const { loading, error, data: userData, refetch: refetchUserData } = useQuery< | |
QueryUserData | |
>(QUERY_USER) | |
const login = async (email: string, password: string) => { | |
return mutateLogin({ | |
variables: { | |
email, | |
password | |
}, | |
update(cache, { data }) { | |
cache.writeQuery({ | |
query: QUERY_USER, | |
data: { | |
me: { | |
__typename: 'auth', | |
id: data?.login.user.id, | |
email: data?.login.user.email | |
} | |
} | |
}) | |
} | |
}) | |
} | |
const logout = async () => { | |
return await mutateLogout({ | |
update(proxy) { | |
proxy.writeQuery({ | |
query: QUERY_USER, | |
data: { | |
me: null | |
} | |
}) | |
} | |
}) | |
} | |
if (loading) { | |
return ( | |
<Box> | |
<Spinner /> | |
</Box> | |
) | |
} | |
if (error) { | |
return ( | |
<Box> | |
<Text>Something wrent wrong</Text> | |
<Button | |
onClick={() => { | |
refetchUserData() | |
}} | |
> | |
Try again | |
</Button> | |
</Box> | |
) | |
} | |
const user = userData?.me | |
return ( | |
<AuthContext.Provider value={{ login, logout, user }}> | |
{children} | |
</AuthContext.Provider> | |
) | |
} | |
export const useAuth = () => { | |
const auth = React.useContext(AuthContext) | |
if (!auth) { | |
throw new Error('useAuth must be used within a AuthProvider.') | |
} | |
return auth | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment