로그인, 회원가입을 react-hook-form 사용해 바꿔보기
import { useMutation } from "@apollo/client"; import { yupResolver } from "@hookform/resolvers/yup"; import { Modal } from "antd"; import { useRouter } from "next/router"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { useRecoilState } from "recoil"; import { accessTokenState } from "../../../../commons/libraries/store"; import { IMutation, IMutationLoginUserArgs, } from "../../../../commons/types/generated/types"; import LogInPageUI from "./Login.presenter"; import { LOGIN_USER } from "./Login.queries"; import * as yup from "yup"; import { ILogInFormData } from "./Login.types"; export const schema = yup.object({ email: yup .string() .email("이메일형식에 맞지 않습니다") .required("이메일을 입력해주세요"), password: yup .string() .matches( /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/, "비밀번호는 영문, 숫자, 특수문자를 포함한 8자리 이내입니다" ) .required("비밀번호를 입력해주세요"), }); export default function LogIn() { const { register, handleSubmit, formState } = useForm<ILogInFormData>({ resolver: yupResolver(schema), mode: "onChange", }); const [accessToken, setAccessToken] = useRecoilState(accessTokenState); const router = useRouter(); const [loginUser] = useMutation< Pick<IMutation, "loginUser">, IMutationLoginUserArgs (LOGIN_USER); const onClickLogIn = async (data: ILogInFormData) => { try { const result = await loginUser({ variables: { email:data.email password:data.password }, }); const accessToken = result.data?.loginUser.accessToken; // 얘를 글로벌스테이트에 담음 얘는 if (!accessToken) { Modal.error({ content: "비밀번호를 확인해주세요" }); return; } setAccessToken(accessToken); // 로컬스토리지에 저장 localStorage.setItem("accessToken", accessToken); // 임시 사용. (나중에 지울예정) void router.push(`/`); } catch (error) { if (error instanceof Error) Modal.error({ content: error.message }); } }; return ( <LogInPageUI // onChangeEmail={onChangeEmail} // onChangePassword={onChangePassword} register={register} handleSubmit={handleSubmit} formState={formState} onClickLogIn={onClickLogIn} /> ); }
import { ILogInPageUIProps } from "./Login.types"; import * as S from "./Login.styles"; import LogInInputsPage from "../../inputs/loginInput/Input"; import LoginUserButtonPage from "../../buttons/loginUserbutton/button"; export default function LogInPageUI(props: ILogInPageUIProps) { return ( <S.LogInPage> <form> {" "} <S.LogIn> <S.LogInTitle>LOGIN PAGE</S.LogInTitle> 이메일{" "} <LogInInputsPage type="text" register={props.register("email")} /> <div>{props.formState.errors.email?.message}</div> 비밀번호{" "} <LogInInputsPage type="password" register={props.register("password")} /> <div>{props.formState.errors.password?.message}</div> <LoginUserButtonPage title={"로그인"} handleSubmit={props.handleSubmit} onClickLogIn={props.onClickLogIn} </LoginUserButtonPage> </S.LogIn>{" "} </form> </S.LogInPage> ); }
import { ILogInInputsProps } from "./input.types"; import * as S from "./input.styles"; export default function LogInInputsPage(props: ILogInInputsProps) { return <S.LogInInput type={props.type} {...props.register} />; }
import { IButtonPageProps } from "./button.types"; import * as S from "./button.styles"; export default function LoginUserButtonPage(props: IButtonPageProps) { return ( <S.LogInButton type="button" onClick={props.handleSubmit(props.onClickLogIn)} {props.title} </S.LogInButton> ); }
import { useMutation } from "@apollo/client"; import { yupResolver } from "@hookform/resolvers/yup"; import { Modal } from "antd"; import { useRouter } from "next/router"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { IMutation, IMutationCreateUserArgs, } from "../../../commons/types/generated/types"; import { withAuthYes } from "../hocs/withAuth"; import CreateUsersUI from "./CreateUsers.presenter"; import { CREATE_USER } from "./CreateUsers.queries"; import * as yup from "yup"; import { IFormDatas } from "../buttons/createUserbutton/button.types"; export const schema = yup.object({ email: yup .string() .email("이메일형식에 맞지 않습니다") .required("필수 형식입니다"), name: yup.string().required("필수 형식입니다"), password: yup .string() .min(4, "최소 4자 이상을 입력해주세요") .matches( /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/, "비밀번호는 영문, 숫자, 특수문자를 포함한 8자리 이내로 적어주세요" ) .required("필수 형식입니다"), }); function CreateUsers() { const { register, handleSubmit, formState } = useForm<IFormDatas>({ resolver: yupResolver(schema), mode: "onChange", }); const router = useRouter(); const [createUser] = useMutation< Pick<IMutation, "createUser">, IMutationCreateUserArgs (CREATE_USER); const onClickCreateUsers = async (data: IFormDatas) => { try { await createUser({ variables: { createUserInput: { email: data.email name: data.name password: data.password, }, }, }); Modal.success({ content: "회원가입이 완료되었습니다" }); void router.push(`/login`); } catch (error) { if (error instanceof Error) Modal.error({ content: error.message }); } }; return ( <CreateUsersUI register={register} handleSubmit={handleSubmit} formState={formState} onClickCreateUsers={onClickCreateUsers} /> ); } export default withAuthYes(CreateUsers);
import CreateUserButtonPage from "../buttons/createUserbutton/button"; import CreateUserInputsPage from "../inputs/createUsersInput/Input"; import { ICreateUsersUIProps } from "./CreateUsers.types"; export default function CreateUsersUI(props: ICreateUsersUIProps) { return ( <> <form> 이메일:{" "} <CreateUserInputsPage type="text" register={props.register("email")} /> <div>{props.formState.errors.email?.message}</div> 이름:{" "} <CreateUserInputsPage type="text" register={props.register("name")} /> <div>{props.formState.errors.name?.message}</div> 비밀번호:{" "} <CreateUserInputsPage type="password" register={props.register("password")} /> <div>{props.formState.errors.password?.message}</div> <CreateUserButtonPage title={"회원가입하기"} handleSubmit={props.handleSubmit} onClickCreateUsers={props.onClickCreateUsers} </CreateUserButtonPage> </form>{" "} </> ); }
import { IButtonPageProps } from "./button.types"; export default function CreateUserButtonPage(props: IButtonPageProps) { return ( <button type="button" onClick={props.handleSubmit(props.onClickCreateUsers)} > {props.title} </button> ); }
회원가입 부분 input은 로그인input 과 동일하기에 따로 생성해주지 않았다.