들어가기
react의 form을 쉽고, 직관적으로 관리함..
react-hook-form 역시 update가 자주 발생하니,
꼭, 공식문서를 참조할 것
npm i rect-hook-form
import { faApple, faInstagram } from '@fortawesome/free-brands-svg-icons'
import styled from 'styled-components'
import { useForm } from 'react-hook-form'
//1. 'react-hook-form'에서 useForm을 불러옴.
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import AuthLayout from '../components/auth/AuthLayout'
import FormBox from '../components/auth/FormBox'
import Input from '../components/auth/Input'
import Button from '../components/auth/Button'
import Separator from '../components/auth/Separator'
import BottomBox from '../components/auth/BottomBox'
import routes from '../routes'
import PageTitle from '../components/PageTitle'
import { gql, useMutation } from '@apollo/client'
import { isLoggedInVar } from '../apollo'
import { LOCALSTORAGE_TOKEN } from '../constant'
import { useLocation } from 'react-router-dom'
const FacebookLogin = styled.div`
color: #385285;
span {
margin-left: 10px;
font-weight: 600;
}
`
const LOGIN_MUTATION = gql`
mutation login($username: String!, $password: String!) {
login(username: $username, password: $password) {
ok
token
error
}
}
`
function Login() {
const location = useLocation()
console.log(location)
const {
register,
handleSubmit,
getValues,
formState: { errors },
} = useForm({
mode: 'onBlur',
defaultValues: {
username: location?.state?.username || '',
password: location?.state?.password || '',
},
})
//2. const {register, handleSubmit, getValues, formState:{errors} = ussForm()
//을 만든다.
// mode는 useForm이 적용되는 시점을 설정(onBlur, onCompleted, onSubmit)
const onCompleted = (data) => {
const {
login: { ok, token, error },
} = data
if (!ok) {
return { ok: false, error }
}
if (token) {
localStorage.setItem(LOCALSTORAGE_TOKEN, token)
isLoggedInVar(true)
}
}
const onValid = (data) => {
if (loading) {
return
}
const { username, password } = getValues()
login({
variables: { username, password },
})
}
//6. form이 submit 됬을떄, 실행 될 함수를 만들어줌.
//useMutation과 결합된 형태임.
//useMutation과 결합전에는 console.log(data)로 form의 값을
//잘 받아오는지 확인한다.
//getValue로 form의 username과 password를 받아와서
//login mutaion의 variables에 값을 넣어준다.
const [login, { loading }] = useMutation(LOGIN_MUTATION, {
onCompleted,
})
return (
<AuthLayout>
<PageTitle title="Login" />
<FormBox>
<div>
<FontAwesomeIcon icon={faInstagram} size="3x" />
</div>
<span style={{ color: 'red', textDecoration: 'underline' }}>
{location?.state?.message}
</span>
<form onSubmit={handleSubmit(onValid)}>
//3. form에 onSubmit={handleSubmit(onValid)}를 만듬.
//그리고 inValid Fn을 만듬(form을 submit했을떄, 실행됨)
<Input
{...register('username', { required: true, minLength: 5 })}
//4. 각각의 input에 {...register}를 등록함
type="text"
placeholder="username"
/>
{errors.username && (
<span style={{ color: 'red', margin: '5px', fontSize: '12px' }}>
This field is required and minLength is five!!
</span>
)}
//5. 각각의 input에 띄울 error 및 error Message 설정함.
<Input
{...register('password', { required: true, minLength: 5 })}
type="password"
placeholder="password"
/>
{errors.pasword && (
<span style={{ color: 'red', margin: '5px', fontSize: '12px' }}>
This field is required and minLength is five!!
</span>
)}
<Button type="submit" value="Log in" />
</form>
<Separator />
<FacebookLogin>
<FontAwesomeIcon icon={faApple} size="2x" />
<span>Login in with AppleStore</span>
</FacebookLogin>
</FormBox>
<BottomBox
cta="Don't have an account?"
linkText="Sign up"
link={routes.signUp}
/>
</AuthLayout>
)
}
export default Login