■ 비밀번호 변경
(1) 기본 UI 작성 후 변경할 값을 받을 Input 의 value를 password, newPassword state 와 연결해주기
const ChangePassword = () => {
const [password, SetPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const { userInfo } = useContext(EntireContext);
// 변경 비밀번호
const onChangePassword = (e) => {
setNewPassword(e.target.value);
};
// 비밀번호 확인
const onChangeCheckPassword = (e) => {
setCheckPassword(e.target.value);
};
return (
<>
<button onClick={handleToggle}>회원정보 수정</button>
<div>
<p>회원정보 수정</p>
<IdBox>
<p>▸ 아이디</p>
<p>{userInfo.email}</p>
</IdBox>
<div>
<label htmlFor="new-password">▸ 변경 비밀번호</label>
<input
type="password"
id="new-password"
value={newPassword}
onChange={onChangePassword}
placeholder="비밀번호"
/>
</div>
<p>비밀번호는 숫자, 영어, 특수문자를 포함한 8자 이상 15자 이하입니다.</p>
<div>
<label htmlFor="check-password">▸ 비밀번호 확인</label>
<input
type="password"
id="check-password"
value={checkPassword}
onChange={onChangeCheckPassword}
placeholder="비밀번호 확인"
/>
</div>
<button>취소</button>
<button>수정</button>
</div>
</>
);
};
(2) 비밀번호 변경 함수 생성 후 수정버튼에 onClick 이벤트로 연결
const handleChangePassword = async () => {
// 정규표현식 파일에 생성한 PASSWORD_REGEX import 후 사용
// (PASSWORD_REGEX = /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$/)
if (newPassword === checkPassword && PASSWORD_REGEX.test(newPassword)) {
await supabase.auth.updateUser({
password: newPassword // 입력받을 값인 newPassword로 패스워드 업데이트
});
toast.success("비밀번호가 변경되었습니다.");
setModal(!modal);
handleSetInit();
} else {
toast.error("올바른 비밀번호 형식이 아닙니다. 다시 입력해주세요.");
handleSetInit();
}
};
// input 초기화 함수
const handleSetInit = () => {
setNewPassword("");
setCheckPassword("");
};
(3) 유효성 검사 메세지 추가
// 변경 비밀번호 입력 시 조회될 메세지
<ConfirmMessage>
{newPassword.length > 0 &&
(PASSWORD_REGEX.test(newPassword) ||
"비밀번호는 숫자, 영어, 특수문자를 포함한 8자 이상 15자 이하입니다.")}
</ConfirmMessage>
// 확인 비밀번호 입력 시 조회될 메세지
<ConfirmMessage>
{checkPassword.length > 0 && (newPassword === checkPassword || "비밀번호가 일치하지 않습니다.")}
</ConfirmMessage>
(4) 회원가입한 사용자에게만 비밀번호 변경 화면이 보이도록 해주기
* 소셜로그인 사용자의 경우 비밀번호 재설정 메일이 해당 소셜계정으로 전송된다.
// userInfo 내 provider 속성으로 소셜로그인 사용자와 일반회원가입 사용자를 구분
const userProvider = userInfo.app_metadata.provider;
return (
{ userProvider === "email" && (회원정보 수정 ~~~) }
)
(5) 모달창 구현하기
// 초기값이 false 인 modal 상태 생성
const [modal, setModal] = useState(false);
// 모달 열고 닫는 함수
const handleClickModal = () => {
setModal(!modal);
handleSetInit();
};
// 모달 적용
<ModalOpenBtn type="button" onClick={handleClickModal}>
회원정보 수정
</ModalOpenBtn>
{modal && (
<Modal onClick={handleClickModal}>
<ModalContainer onClick={(e) => e.stopPropagation()}>
<CloseBtn onClick={handleClickModal}>✖</CloseBtn>
<p>회원정보 수정</p>
<ModalContents>
<p>▸ 아이디</p>
<EmailText>{userInfo.email}</EmailText>
<label htmlFor="new-password">▸ 변경 비밀번호</label>
<PasswordInput
type="password"
id="new-password"
value={newPassword}
onChange={onChangePassword}
placeholder="비밀번호"
/>
<ConfirmMessage>
{newPassword.length > 0 &&
(PASSWORD_REGEX.test(newPassword) ||
"비밀번호는 숫자, 영어, 특수문자를 포함한 8자 이상 15자 이하입니다.")}
</ConfirmMessage>
<label htmlFor="check-password">▸ 비밀번호 확인</label>
<PasswordInput
type="password"
id="check-password"
value={checkPassword}
onChange={onChangeCheckPassword}
placeholder="비밀번호 확인"
/>
<ConfirmMessage>
{checkPassword.length > 0 && (newPassword === checkPassword || "비밀번호가 일치하지 않습니다.")}
</ConfirmMessage>
</ModalContents>
<ConfirmBtn onClick={handleClickModal}>취소</ConfirmBtn>
<ConfirmBtn name="confirm" onClick={handleChangePassword}>
확인
</ConfirmBtn>
</ModalContainer>
</Modal>
)}
(6) styled-components 로 css 적용
- 취소, x 버튼, 모달바깥화면 클릭 시 수정화면 수정모드 꺼짐
■ 발생했던 문제
비밀번호 유효성 검사를 위해 메세지 상태들을 만들어서 각 메세지 상태를 화면에 띄우게 했었는데 리렌더링 문제로 비밀번호 1자리씩 덜 읽으면서 메세지를 보여주는 오류가 발생했다.
const [passwordMessage, setPasswordMessage] = useState("");
const [confirmMessage, setConfirmMessage] = useState("");
■ 해결 방법
비밀번호를 구현했던 팀원분과 같이 코드를 보고 메세지를 상태로 만들기보다는 &&, || 와 같은 논리연산자로 구현해보라는 조언을 듣고 return 문 안에서 논리연산자로 구현하니 입력하는 값에 따라 바로바로 반응하는 것을 확인할 수 있었다.
{newPassword.length > 0 &&
(PASSWORD_REGEX.test(newPassword) ||
"비밀번호는 숫자, 영어, 특수문자를 포함한 8자 이상 15자 이하입니다.")}
{checkPassword.length > 0 && (newPassword === checkPassword || "비밀번호가 일치하지 않습니다.")}
■ 느낀점
팀 프로젝트를 하면서 팀원들이 작성한 코드를 보고 활용도 해보면서 좀더 간결하고 쉬운 방법을 익힐 수 있었고 막히는 부분이 있을 때마다 팀원들과 질문하면서 하나씩 해결해가는 과정을 통해 프로젝트 전보다 로직 구현방법에 대해 좀 더 다양하게 생각 할 수 있게 된 것 같다.
'TIL' 카테고리의 다른 글
git pull 동기화 전략 (0) | 2024.09.05 |
---|---|
뉴스피드 팀 프로젝트 ⑤ - 마무리, 회고 (1) | 2024.09.04 |
뉴스피드 팀 프로젝트 ③ - 기능구현(내가 작성한 게시물) (0) | 2024.09.02 |
뉴스피드 팀 프로젝트 ② - 기능구현(프로필, 닉네임) (0) | 2024.08.30 |
뉴스피드 팀 프로젝트 ① - 기획 (7) | 2024.08.28 |