20210305 17일차 회원가입 로직 구현 완료
금일 구현 사항
-
회원가입 로직 구현
- 로그인 유무에 따른 페이지 구성 변경
- 반응형 웹 개선
1. 회원가입 로직 구현
기존의 모달창을 이용하여 유효성 검사 메세지를 보여주는 방식의 경우 완료 버튼을 눌러야만 잘못된 부분을 확인할 수 있기 때문에사용자의 입장에서 매우 불편할 것으로 판단했다.
이를 개선하기 위해 잘못된 형식의 정보를 기입하거나 동일한 정보(이메일, 전화번호, 닉네임)가 존재할 때, 글자를 입력할 때마다 해당 유효성 검사를 하여 사진 밑과 같이 메세지를 노출시켜 유저가 확인하기 용이하게 구현했다.
특히, 팀 전체의 의견을 수렴하여 별명/전자우편/전화번호의 경우, 글자를 입력할 때마다 동일한 정보가 데이터베이스에 존재하는지 서버에 확인하여 response 에 따라 유저에게 사용가능 여부 메세지를 보여주는 방식으로 구현했다.
예) 동일한 이메일이 있는지 확인하는 로직
const handleEmail = async (event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
// 이메일 형식에 맞으면 validEmail: true
if (isEmailForm(email)) {
setValidation({
...validation,
validEmail: isEmailForm(event.target.value),
});
setMsgVisible(false);
await axios
.post(
"https://royal-diary.ml/users/matchinfo",
{ email: event.target.value },
{
headers: { "Content-Type": "application/json" },
withCredentials: true,
}
)
.then((res) => {
if (res.data.message === "email is usable") {
setIsUsableEmail(true);
setMessage("사용가능한 이메일입니다.");
setMsgVisible(true);
} else if (res.data.message === "email already exists") {
setIsUsableEmail(false);
setMessage("동일한 이메일이 존재합니다.");
setMsgVisible(true);
}
})
.catch((err) => {
console.log(err);
});
} else {
setMessage("이메일 형식을 확인해주세요");
setMsgVisible(true);
}
};
이메일이 형식에 맞게 작성되었는지 먼저 확인한 뒤(isEmailForm(email) === true 인 경우) 서버로 입력한 이메일 값을 보내
사용 가능여부에 대한 응답을 받는다. 그리고 유저에게 메세지를 띄운다.
그리고, 유저가 모두 기입하고 제출 버튼을 누르면 모든 기입 정보의 사용가능 여부를 확인한 뒤 미흡한 경우 관련 메세지를 보낸다.만약 모든 조건을 만족하면 아래와 같이 서버에 회원가입 요청을 보낸다.
await axios
.post(
"https://royal-diary.ml/users/signup",
{
name,
email,
password: lastPassword,
nickname: nickName,
mobile,
},
{
headers: { "Content-Type": "application/json" },
withCredentials: true,
}
)
.then((res) => {
sessionStorage.setItem("accessToken", res.data.data.accessToken);
sessionStorage.setItem("isLogin", JSON.stringify(true));
sessionStorage.setItem("nickName", nickName);
setSignUpModal(true);
setModalMessage("회원가입 되었습니다");
setModalVisible(true);
})
.catch((error) => {
const errResponse = error.response.data.message;
console.log(errResponse);
});
} else {
setModalMessage("모든 입력사항은 필수 입니다.");
setModalVisible(true);
}
서버로부터 accessToken 을 받아오면 이 토큰과 로그인true, 닉네임을 세션 스토리지에 담아주었는데, 이는 전역에서 이 세션스토리지의 데이터를 사용할 수 있고, 무엇보다 유저가 페이지를 껐을때 토큰과 로그인정보를 삭제함으로써 보안성을 높이기 위해서이다. 이 전의 프로젝트에서는 localstorage 를 사용했기 때문에 페이지를 꺼도 로그인과 토큰이 유지되었기에 보안에 취약했다.
그리고 유효성 검사 메세지를 띄우기 위해 react element 의 속성인 theme property 를 사용했는데, 코드는 아래와 같다.
theme 을 통해 msgVisible 상태의 true/false 값을 styled component 의 display 에 props 로 전달하는 방식이다.
물론 더 좋은 방법이 있을테지만... 일단은 theme 을 사용하여 구현했다.
return (
<Main>
<div id="wrap">
<ValidityBox theme={msgVisible}>{message}</ValidityBox>
</div>
<InfoBox>
중략....
const ValidityBox = styled.div`
/* border: 3px solid red; */
position: relative;
width: 12rem;
height: 30px;
margin-right: 1.1rem;
padding-left: 0.6rem;
background: #f08080;
display: ${(props) => (props.theme === true ? "flex" : "none")};
border-radius: 10px;
justify-content: flex-start;
align-items: center;
::after {
border-top: 0px solid transparent;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid #f08080;
content: "";
position: absolute;
top: -10px;
left: 120px;
}
animation: a 2s;
모달창은 완료버튼을 눌렀을때 기입된 정보가 하나라도 부족한 경우에만 띄울 수 있게 했다.
2. 로그인유무에 따른 페이지 구성(회원가입 완료 후 자동 로그인)
회원 가입을 한 뒤에 확인 버튼을 누르면 메인 페이지로 이동하게 되는데 아래와 같이 (닉네임) 의 그림일기장 으로 출력된다.
버튼도 정상적이라면 로그아웃 버튼만 나와야 하는데..... 다시 고쳐야겠다.
로그인 상태가 아닐 경우 메인페이지는 네이게이션 바에 일기쓰기, 훔쳐보기, 제작자와 로그인/회원가입/소샬로그인 버튼이 구성된다. 이는 useEffect 를 사용하여 페이지가 새로 렌더링될 때 세션 스토리지의 signin 상태에 따라 동작하는 방법으로 구현했다.
도움받은 참고자료
1. localStrorage(SessionStorage) 사용법 관련 코드
2. 다음에 사용해볼 styled component props 사용법
3. conditional rendering in styled components
4. useEffect 사용법
useEffect?
리액트의 class 생명주기 메서드에 친숙하다면, useEffect Hook을 componentDidMount와 componentDidUpdate, componentWillUnmount가 합쳐진 것으로 생각해도 좋습니다.
useEffect가 하는 일은 무엇일까요? useEffect Hook을 이용하여 우리는 리액트에게 컴포넌트가 렌더링 이후에 어떤 일을 수행해야하는 지를 말합니다. 리액트는 우리가 넘긴 함수를 기억했다가(이 함수를 ‘effect’라고 부릅니다) DOM 업데이트를 수행한 이후에 불러낼 것입니다. 위의 경우에는 effect를 통해 문서 타이틀을 지정하지만, 이 외에도 데이터를 가져오거나 다른 명령형(imperative) API를 불러내는 일도 할 수 있습니다.
useEffect 에 빈배열을 넣는 이유