스파르타코딩클럽 내일배움캠프 TIL70

한재창·2023년 2월 8일
0

최종프로젝트

회원가입

  • 처음에는 useState를 한개씩 주어 onChange함수를 여러개 생성하였다.
const [nickName, setNickname] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')

   const nickNameChangeHandler = (event: React.FormEvent<HTMLInputElement>) => {
      setNickName(event.currentTarget.value);
    };

   const emailChangeHandler = (event: React.FormEvent<HTMLInputElement>) => {
      setEmail(event.currentTarget.value);
    };

   const passwordChangeHandler = (event: React.FormEvent<HTMLInputElement>) => {
      setPassword(event.currentTarget.value);
    };
  • 코드가 중복되는 게 많다고 생각해서 찾아보았더니 HTML 태그마다 name 값을 넣어 수정되는 'key' 값에 넣어주어 코드를 줄였다.
  • 회원가입 버튼을 누르면 파이어베이스에서 제공해주는 함수 createUserWithEmailAndPassword를 사용해서 회원가입이 되도록 하였다.
  • 회원가입 버튼 클릭시 발동하는 함수 순서
    • 파이어베이스 auth 에 회원가입 데이터가 저장된다.
    • 회원가입 후 바로 updateProfile 함수를 사용해 닉네임을 업데이트 한다.
    • 파이어스토어에 users 정보를 저장한다.
      • 나중에 성별과 나이대를 이용한 통계를 내기 위해서 저장해주었다.
import { useState } from 'react';
import { auth, db } from '../../firebase';
import {
  createUserWithEmailAndPassword,
  updateProfile,
} from 'firebase/auth';
import { doc, setDoc } from 'firebase/firestore';
import SignOut from './SignOut';
import DeleteAccount from './DeleteAccount';
import SignIn from './SignIn';

interface SignUpInput {
  nickName: string;
  email: string;
  password: string;
  passwordCheck: string;
  gender: string;
  age: string;
  phoneNumber: string;
  phoneCode: string;
}

const SignUp = () => {
  const initSignUpInput = {
    nickName: '',
    email: '',
    password: '',
    passwordCheck: '',
    gender: '',
    age: '',
    phoneNumber: '',
    phoneCode: '',
  };

  const [signUpInput, setSignUpInput] = useState<SignUpInput>(initSignUpInput);

  const signUpInputChangeHandler = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    setSignUpInput({
      ...signUpInput,
      [event.target.name]: event.target.value,
    });
  };

  const signUpSelectChanchHandler = (
    event: React.ChangeEvent<HTMLSelectElement>,
  ) => {
    setSignUpInput({
      ...signUpInput,
      [event.target.name]: event.target.value,
    });
  };

  // 회원가입 클릭 이벤트
  const singUpHandler = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    await createUserWithEmailAndPassword(
      auth,
      signUpInput.email,
      signUpInput.password,
    )
      .then(({ user }) => {
        // 회원가입하고 바로 프로필 업데이트
        updateProfile(user, {
          displayName: signUpInput.nickName,
        });
        // 회원가입하고 바로 데이터베이스 저장
        setDoc(doc(db, 'users', user.uid), {
          uid: user.uid,
          nickName: user.displayName,
          profileImg: user.photoURL,
          email: signUpInput.email,
          gender: signUpInput.gender,
          age: signUpInput.age,
        });
        // input값 초기화
        setSignUpInput(initSignUpInput);
      })
      .catch((error) => {
		console.log(error);
      });
  };

  return (
    <div>
      <form onSubmit={singUpHandler}>
        <h3>닉네임</h3>
        <input
          onChange={signUpInputChangeHandler}
          value={signUpInput.nickName}
          name="nickName"
          type="text"
        />
        <div style={{ color: 'red' }}>{helperText.nickName}</div>
        <h3>이메일</h3>
        <input
          onChange={signUpInputChangeHandler}
          value={signUpInput.email}
          name="email"
          type="email"
        />
        <div style={{ color: 'red' }}>{helperText.email}</div>
        <h3>비밀번호</h3>
        <input
          onChange={signUpInputChangeHandler}
          value={signUpInput.password}
          name="password"
          type="password"
        />
        <div style={{ color: 'red' }}>{helperText.password}</div>
        <h3>비밀번호 확인</h3>
        <input
          onChange={signUpInputChangeHandler}
          value={signUpInput.passwordCheck}
          name="passwordCheck"
          type="password"
        />
        <div style={{ color: 'red' }}>{helperText.passwordCheck}</div>
        <h3>성별</h3>
        <select
          value={signUpInput.gender}
          name="gender"
          onChange={signUpSelectChanchHandler}
        >
          <option value="">성별을 선택해 주세요</option>
          <option value="남자">남자</option>
          <option value="여자">여자</option>
          <option value="선택안함">선택안함</option>
        </select>
        <div style={{ color: 'red' }}>{helperText.gender}</div>
        <h3>연령</h3>
        <select
          value={signUpInput.age}
          name="age"
          onChange={signUpSelectChanchHandler}
        >
          <option value="">연령을 선택해 주세요</option>
          <option value="10대">10</option>
          <option value="20대">20</option>
          <option value="30대">30</option>
          <option value="40대">40</option>
          <option value="50대">50</option>
          <option value="60대">60</option>
          <option value="70대">70</option>
          <option value="선택안함">선택안함</option>
        </select>
        <div style={{ color: 'red' }}>{helperText.age}</div>
        <button>가입</button>
      </form>
      <SignOut />
      <DeleteAccount />
      <SignIn />
    </div>
  );
};

export default SignUp;

로그인

  • 로그인 버튼을 누르면 파이어베이스에서 제공하는signInWithEmailAndPassword 함수를 이용해 회원가입 했던 아이디로 로그인이 되게 해주었다.
  • 로그인 버튼 클릭시 발동하는 함수 순서
    • 로그인이 되고 인풋창을 빈 값으로 만들어준다.
    • 홈페이지로 이동한다.
import { signInWithEmailAndPassword } from 'firebase/auth';
import { useState } from 'react';
import { auth } from '../../firebase';

interface SignInInput {
  email: string;
  password: string;
}

const SignIn = () => {
  const initSignInInput = {
    email: '',
    password: '',
  };

  const [signInInput, setSignInInput] = useState<SignInInput>(initSignInInput);

  const signInInputChangeHandler = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    setSignInInput({
      ...signInInput,
      [event.target.name]: event.target.value,
    });
  };

  // 로그인 이벤트
  const signInClickHandler = async (
    event: React.FormEvent<HTMLFormElement>,
  ) => {
    event.preventDefault();

    await signInWithEmailAndPassword(
      auth,
      signInInput.email,
      signInInput.password,
    )
      .then((userCredential) => {
        setSignInInput(initSignInInput);
        window.location.href = '/';
      })
      .catch((error: any) => {
        console.log(error);
      });
  };

  return (
    <form onSubmit={signInClickHandler}>
      <h3>ID</h3>
      <input
        value={signInInput.email}
        name="email"
        type="text"
        onChange={signInInputChangeHandler}
      />
      <div style={{ color: 'red' }}>{helperText.email}</div>
      <h3>PW</h3>
      <input
        value={signInInput.password}
        name="password"
        type="password"
        onChange={signInInputChangeHandler}
      />
      <div style={{ color: 'red' }}>{helperText.password}</div>
      <button>로그인</button>
    </form>
  );
};

export default SignIn;

로그아웃

  • 로그아웃 버튼을 누르면 파이어베이스에서 제공하는signOut 함수를 이용해 로그아웃이 되게 해주었다.
import { signOut } from 'firebase/auth';
import { auth } from '../../firebase';

const SignOut = () => {
  // 로그아웃 이벤트
  const SignOutClickHandler = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    try {
      signOut(auth);
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <form onSubmit={SignOutClickHandler}>
      <button>로그아웃</button>
    </form>
  );
};

export default SignOut;

회원탈퇴

  • 회원탈퇴 버튼을 누르면 파이어베이스에서 제공하는deleteUser 함수를 이용해 회원탈퇴 되게 해주었다.
  • 회원탈퇴 버튼 클릭시 발동하는 함수 순서
    • 회원탈퇴
    • 파이어스토어에 저장된 users에서 데이터를 제거한다.
import { deleteUser } from 'firebase/auth';
import { deleteDoc, doc } from 'firebase/firestore';
import { auth, db } from '../../firebase';

const DeleteAccount = () => {
  const user = auth.currentUser;
  // 회원탈퇴 할 때 데이터베이스에서 삭제해야하기 때문에 함수를 만듦
  const deleteDocUser = async (id: any) => {
    try {
      await deleteDoc(doc(db, 'users', id));
    } catch (error) {
      alert(error);
    }
  };

  // 회원탈퇴 이벤트
  const deleteAccountClickHandler = (
    event: React.FormEvent<HTMLFormElement>,
  ) => {
    event.preventDefault();
    if (user) {
      try {
        deleteUser(user);
        deleteDocUser(user.uid);
      } catch (error) {
        console.log(error);
      }
    }
  };

  return (
    <form onSubmit={deleteAccountClickHandler}>
      <button>회원탈퇴</button>
    </form>
  );
};

export default DeleteAccount;
profile
취준 개발자

0개의 댓글