주요 기능 | 회원가입 - itsyuna/Foot-Salon GitHub Wiki

Sign Up

Redux Toolkit을 사용하여 User 상태 관리

Firebase로 User 정보 관리

정규 표현식을 활용하여 닉네임/이메일/비밀번호 검증 기능 구현


✔️ 닉네임,이메일 중복 체크

✔️ Form 공백 시 / 형식에 맞지 않을 시 안내 문구 활성화


💻 Code

SignUp.tsx
// 닉네임 중복 체크
const checkNickname = (
    nicknameInput: React.ChangeEvent<HTMLInputElement>
  ) => {
    const queryNicknameCheck = query(
      collection(dbService, "userList"),
      where("userNickname", "==", nicknameInput)
    );

    onSnapshot(queryNicknameCheck, (querySnapshot) => {
      if (querySnapshot.empty) {
        setNicknameCheckText("사용 가능한 닉네임입니다 :)");
      } else setNicknameCheckText("이미 사용 중인 닉네임입니다 :(");
    });
  };

const onSubmit = async (data: FormData) => {
    ...

   try {
     const { user } = await createUserWithEmailAndPassword(
      auth,
      data.email,
      data.password
     );

     await updateProfile(user, { displayName: data.nickname });

     await setDoc(doc(dbService, "userList", user.uid), {
       userNickname: user.displayName,
       userEmail: user.email,
     });
      
     // 회원가입 성공 시 바로 로그인
     dispatch(
       userActions.login({
         userNickname: user.displayName,
         userEmail: user.email,
         userUid: user.uid,
       })
     );

     toast.success("Welcome to Foot Salon! ⚽️🙌🏻");
     navigate("/");
   } catch (error) {
      if (error instanceof Error) {
        // 이메일 중복 체크
        if (error.message.includes("auth/email-already-in-use")) {
          toast.warning("이미 사용 중인 이메일입니다 :(");
        } else toast.error("오류가 발생했습니다 :(");
      }
   }
};

return (
        ...
        <form onSubmit={handleSubmit(onSubmit)}>				
          <Controller
            control={control}
            defaultValue=""
            name="nickname"
            rules={{
              required: "필수 입력 사항입니다.",
              pattern: {
                // 정규표현식을 활용하여 검증
                value: /^[0-9|a-z|A-Z|-|-|-]*$/,
                message: "특수문자 or 공백을 제거해 주세요.",
              },
              onChange(e) {
                checkNickname(e.target.value);
              },
            }}
            render={({ field }) => (
              <InputWrapper>
                <Label htmlFor="nickname">닉네임</Label>
                <CheckInput
                  type="text"
                  id="nickname"
                  placeholder="한글,영문 사용 가능(최대 12글자) / 띄어쓰기,특수문자 사용 불가"
                  autoComplete="off"
                  value={field.value}
                  onChange={field.onChange}
                  maxLength={12}
                />
		// 닉네임 중복 체크 메시지
                <ErrorText>{!errors.nickname && nicknameCheckText}</ErrorText>
              </InputWrapper>
            )}
          />
          // Form 공백 시/형식에 맞지 않을 시 안내 문구 활성화
          <ErrorText>{errors.nickname && errors.nickname.message}</ErrorText>
         ...

🖥 View

SignUp page SignUp page
에러 처리

🔻 Form이 공백일 시
Form이 공백일 시


🔻 Form 형식에 맞지 않을 시
Form 형식에 맞지 않을 시


🔻 닉네임이 중복일 경우
닉네임이 중복일 경우

⚠️ **GitHub.com Fallback** ⚠️