react-hook-form
햇갈리는 error부분만 잘 봐둔다.
useMutation은 빼고 react-hook-form부분만 다룬다.
select부분과
formState:{errors}를 잘 봐둔다.!!!!
import { gql, useMutation } from '@apollo/client'
import React from 'react'
import { useForm } from 'react-hook-form'
import { Link } from 'react-router-dom'
import { authTokenVar, isLoggedInVar } from '../apollo'
import Button from '../components/button'
import { FormError } from '../components/form-error'
import { LoginMutation, LoginMutationVariables } from '../graphql/__generated__'
import { LOCALSTORAGE_TOKEN } from '../constant'
interface ILoginForm {
email: string
password: string
}
const LOGIN_MUTATION = gql`
mutation login($loginInput: LoginInput!) {
login(input: $loginInput) {
ok
token
error
}
}
`
export const Login = () => {
const {
register,
getValues,
formState: { errors, isValid },
handleSubmit,
} = useForm<ILoginForm>({
mode: 'onChange',
})
///useForm으로 만들고 mode는 onChange,
///register, getValues, handleSubmit, formState:{errors, isValid}를 넣는다.
const onCompleted = (data: LoginMutation) => {
const {
login: { ok, token },
} = data
if (ok && token) {
console.log(token)
localStorage.setItem(LOCALSTORAGE_TOKEN, token)
authTokenVar(token)
isLoggedInVar(true)
}
}
const [loginMutation, { data: loginMutationResult, loading }] = useMutation<
LoginMutation,
LoginMutationVariables
>(LOGIN_MUTATION, { onCompleted })
const onSubmit = () => {
///email과 password 값을 form으로부터 getValues()한다.
///그리고 loginMutation의 variables로 보내준다.
if (!loading) {
const { email, password } = getValues()
loginMutation({
variables: {
loginInput: {
email,
password,
},
},
})
}
}
return (
<div className="h-screen flex items-center justify-center flex-col">
<div className="w-full max-w-screen-sm flex flex-col px-5 items-center">
<h3 className="w-full font-medium text-left text-3xl mb-5">
Welcome Back
</h3>
<form
onSubmit={handleSubmit(onSubmit)}
className="grid gap-3 mt-3 mb-5 w-full"
>
///react-hook-form 형태를 잘 봐둔다.
///formState:{error, isValid}부분이
///헷갈리니 잘 봐둔다..
<input
{...register('email', {
required: 'Email is required',
maxLength: { value: 30, message: 'max char is 30' },
})}
required
maxLength={30}
type="email"
placeholder="Email"
className="input"
/>
{errors.email?.message && (
<FormError errorMessage={errors.email.message} />
)}
<input
{...register('password', { required: 'Password is required' })}
name="password"
type="password"
placeholder="Password"
className="input"
/>
{errors.password?.message && (
<FormError errorMessage={errors.password?.message} />
)}
///Button component를 import함.
///component는 나중에 따로 다룰 예정!
<Button loading={loading} actionText="Login" />
{loginMutationResult?.login.error && (
<FormError errorMessage={loginMutationResult?.login.error} />
)}
</form>
<p className="text-center mt-5 text-base">
계정이 없으신가요?
<Link
to="/signup"
className="ml-2 font-semibold text-green-600 hover:underline"
>
회원가입
</Link>
</p>
</div>
</div>
)
}
***react-hook-form부분만 집중적으로 다뤄본다.
import { gql, useMutation } from '@apollo/client'
import React from 'react'
import { useForm } from 'react-hook-form'
import { Link } from 'react-router-dom'
import { useNavigate } from 'react-router-dom'
import Button from '../components/button'
import { FormError } from '../components/form-error'
import {
CreateAccoountMutation,
CreateAccoountMutationVariables,
UserRole,
} from '../graphql/__generated__'
export const CREATE_ACCOUNT = gql`
mutation createAccoount($createAccountInput: CreateAccountInput!) {
createAccount(input: $createAccountInput) {
ok
error
}
}
`
interface ICreateAccountForm {
email: string
password: string
role: UserRole
}
export const CreateAccount = () => {
///위의 login이랑 같음...
const {
register,
getValues,
formState: { errors, isValid },
handleSubmit,
} = useForm<ICreateAccountForm>({
mode: 'onChange',
defaultValues: { role: UserRole.Client },
})
const navigate = useNavigate()
const onCompleted = (data: CreateAccoountMutation) => {
const {
createAccount: { ok },
} = data
if (ok) {
alert('Account Created. Log in now.')
}
}
const [createAccountMutation, { loading, data: createAccountMutaionResult }] =
useMutation<CreateAccoountMutation, CreateAccoountMutationVariables>(
CREATE_ACCOUNT,
{ onCompleted }
)
const onSubmit = () => {
///getValues해서 값을 variables:{createAccountInput에 보내줌..
///createAccountMutation을 실행
if (!loading) {
const { email, password, role } = getValues()
createAccountMutation({
variables: {
createAccountInput: { email, password, role },
},
})
}
}
return (
<div className="h-screen flex flex-col items-center justify-center ">
<div className="w-full max-w-screen-sm flex flex-col px-5 items-center">
<h4 className="w-full font-medium text-lleft text-3xl mb-5">
Let's get started
</h4>
<form
onSubmit={handleSubmit(onSubmit)}
className="grid gap-3 mt-5 mb-5 w-full"
>
<input
///react-hook-form형태!!!
///error 다루는 거만 집중해서 보자
{...register('email', { required: 'Email is required' })}
className="input"
placeholder="email"
type="email"
required
/>
{errors.email?.message && (
<FormError errorMessage={errors.email?.message} />
)}
<input
{...register('password', { required: 'Password is Required' })}
className="input"
placeholder="password"
type="password"
required
/>
{errors.password?.message && (
<FormError errorMessage={errors.password?.message} />
)}
///select다루는 부분 집중해서 봐둘것!!!!
<select {...register('role', { required: true })} className="input">
{Object.keys(UserRole).map((role, index) => (
<option key={index}>{role}</option>
))}
</select>
<Button loading={loading} actionText="Create Account" />
</form>
<div className="text-lg">
Already have an account?{''}
<Link to="/" className="text-green-400 hover:underline">
Log in now
</Link>
</div>
</div>
</div>
)
}
export default CreateAccount
!!!NOTICE select다루는 부분 집중해서 봐둔다
!!! formState:{error}다루는부분이랑.