nextjs commerce 에서 login 의 동작
login button click 시
- LoginView 에서 submit button 을 누르면,
useLogin
을 호출한다. useLogin
은 현재의 provider에서auth.useLogin
을 가져오고,useMutationHook
을 호출하면서 그것을 parameterhook
으로 보낸다.- 그러면,
useMutationHook
에서hook.useHook
을 호출한다. 즉,provider.auth.useLogin.useHook
을 호출하게 되는 것이다.
useHook
은 다시 그 안에서, fetch 를 호출하는데, 이안에서 다시useLogin.fetcher
를 호출하게 된다.useLogin.fetcher
에서 mutation 을 보내게 된다.
// components/auth/LoginView.tsx
...
const LoginView: React.FC = () => {
...
const login = useLogin()
const handleLogin = async (e: React.SyntheticEvent<EventTarget>) => {
...
try {
setLoading(true)
setMessage('')
// --> packages/commerce/src/auth/use-login.tsx
await login({
email,
password,
})
...
} catch ({ errors }) {
...
} finally {
setLoading(false)
}
}
...
return (
<form
onSubmit={handleLogin}
className="w-80 flex flex-col justify-between p-3"
>
...
</form>
)
}
export default LoginView
// packages/commerce/src/auth/use-login.tsx
export type UseLogin<
H extends MutationHook<LoginHook> = MutationHook<LoginHook>
> = ReturnType<H['useHook']>
export const fetcher: HookFetcherFn<LoginHook> = mutationFetcher
const fn = (provider: Provider) => provider.auth?.useLogin!
const useLogin: UseLogin = (...args) => {
// --> packages/commerce/src/utils/use-hook.ts
const hook = useHook(fn)
// --> packages/commerce/src/utils/use-hook.ts
return useMutationHook({ fetcher, ...hook })(...args)
}
export default useLogin
// packages/commerce/src/utils/use-hook.ts
export function useHook<
P extends Provider,
H extends MutationHook<any> | SWRHook<any>
>(fn: (provider: P) => H) {
const { providerRef } = useCommerce<P>()
const provider = providerRef.current
return fn(provider)
}
...
export function useMutationHook<H extends MutationHook<any>>(
hook: PickRequired<H, 'fetcher'>
) {
const fetcher = useFetcher()
// --> packages/vendure/src/auth/use-login.tsx
return hook.useHook({
fetch: useCallback(
({ input } = {}) => {
// --> packages/vendure/src/auth/use-login.tsx
return hook.fetcher({
input,
options: hook.fetchOptions,
fetch: fetcher,
})
},
[fetcher, hook.fetchOptions]
),
})
}
// packages/vendure/src/auth/use-login.tsx
export default useLogin as UseLogin<typeof handler>
export const handler: MutationHook<LoginHook> = {
...
async fetcher({ input: { email, password }, options, fetch }) {
if (!(email && password)) {
throw new CommerceError({
message: 'A email and password are required to login',
})
}
const variables: LoginMutationVariables = {
username: email,
password,
}
const { login } = await fetch<LoginMutation>({
...options,
variables,
})
if (login.__typename !== 'CurrentUser') {
throw new ValidationError(login)
}
return null
},
useHook:
({ fetch }) =>{
return () => {
const { mutate } = useCustomer()
return useCallback(
async function login(input) {
// --> packages/commerce/src/utils/use-hook.ts
const data = await fetch({ input })
await mutate()
return data
},
[fetch, mutate]
)
}
},
}
아래와 같은 graphql 을 보내게 된다.
{"query":"
mutation login($username: String!, $password: String!) {
login(username: $username, password: $password) {
__typename
... on CurrentUser {
id
}
... on ErrorResult {
errorCode
message
}
}
}
","variables":{"username":"gaedduck@gmail.com","password":"ldldlldfgpassword"}}
댓글 없음:
댓글 쓰기