react-hook-form(1), Login

김종민·2022년 5월 1일
0

insta-reactJS

목록 보기
6/27

들어가기
react의 form을 쉽고, 직관적으로 관리함..
react-hook-form 역시 update가 자주 발생하니,
꼭, 공식문서를 참조할 것

npm i rect-hook-form

1. src/screens/Login.js

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
profile
코딩하는초딩쌤

0개의 댓글