useMutation(2)_Login.js

김종민·2022년 5월 1일
0

insta-reactJS

목록 보기
9/27

import { faApple, faInstagram } from '@fortawesome/free-brands-svg-icons'
import styled from 'styled-components'
import { useForm } from 'react-hook-form'
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'

///1.'@apollo/client'로부터 gql과 useMutation을 불러온다.

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
    }
  }
`
//2. LOGIN_MUTATION을 만든다.
//만들어지는 벙법은 backend공부할때, playground에 타이핑되던, 코드와 같음.
//ok, token, error를 backend(server)로 부터 return받음.


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 || '',
    },
  })

  const onCompleted = (data) => {
    const {
      login: { ok, token, error },
    } = data
    if (!ok) {
      return { ok: false, error }
    }
    if (token) {
      localStorage.setItem(LOCALSTORAGE_TOKEN, token)
      isLoggedInVar(true)
    }
  }
  ///5. login mutataion이 시작되고(onValid)고 완료 시킬떄의 fn,
  ///fn의 data는 login mutation이 실행되고 나서 server로 부터 받는 data임
  //ok를 받지 못하면 return{ ok: false를 보냄}
  //success해서 token을 받으면, localStorage의 LOCALSTORAGE에 토큰을 넣어줌(setItem)
  //그리고 isLoggedInVar를 true로 바꿔줌.
  

  const onValid = (data) => {
    if (loading) {
      return
    }
    const { username, password } = getValues()
    login({
      variables: { username, password },
    })
    ///4. react-hook-form의 onValid에서 form에서 얻은 
    ///data(username, password)를 login mutation의
    ///variables 값에 넣어줌.
    
  }

  const [login, { loading }] = useMutation(LOGIN_MUTATION, {
    onCompleted,
  })
  //3. const[ 뮤태이션 네임(login), {loading} ] = useMutation(2번의 이름, {
  //mutaion이 실행됬을떄 실행될 함수, 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)}>
          <Input
            {...register('username', { required: true, minLength: 5 })}
            type="text"
            placeholder="username"
          />
          {errors.username && (
            <span style={{ color: 'red', margin: '5px', fontSize: '12px' }}>
              This field is required and minLength is five!!
            </span>
          )}
          <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개의 댓글