최종프로젝트
회원가입
- 처음에는
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,
});
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;