중복검사
- 앞서 onBlur에서 호출한 onClickIdDup에서 idChecker를 통해 공백과 정규식 검사를 통과했다면 다음은 중복검사이다.
- 중복검사는 서버와의 비동기통신을 통해 검증하면 된다.
- 나의 경우는 redux-toolkit을 사용했다.
- 우선 get요청으로 서버에 쿼리스트링으로 이메일을 보내준다.
- 이 경우 나는 input의 velue가 전달되는 쿼리스트링 값이다.
- dispatch(__duplicate_check(id));
- /duplicate_check?member_id=${encodeURIComponent(member_id)} 이때 이런식으로 encodeURI를 사용해주면 이메일의 경우 @이나 .의 특수문자를 오류없이 잘 보낼 수 있다.
- 이제 slice에서 initialState에 checkIdDupResult라는 전역상태를 만들어주고 비동기 통신의 결과로 이 전역상태를 컨트롤해서
- 회원가입시 에러메시지가 이메일 폼이 아닌경우와 중복검사가 동시에 나오는 경우를 막을 것이다.
.addCase(__duplicate_check.rejected, (state, action) => {
state.checkIdDupLoading = false;
state.checkIdDupError = action.payload;
console.log(action.payload.error.message);
if (action.payload.error.message === "Invalid ID format")
state.checkIdDupResult = true;
else if (action.payload.error.message === "Duplicate or unavailable ID")
state.checkIdDupResult = false;
}),
- 중복검사가 서버에서 통과되었다면 단순히 checkIdDupResult를 true로 해주면 된다.
- 하지만 만약 중복된 이메일일 경우 서버로 부터 이 이메일이 잘못된 이메일 폼이라서인지 아니면 중복된 이메일인지를 분별해서 받고
- 그에 맞춰 조건문으로 checkIdDupResult의 값을 바꿔주면 된다.
- 이 과정에서 checkIdDupResult를 selector로 구독해주고 값이 변하면 useEffect를 통해 idDupCheck의 값을 변경해줍니다.
- setIdDupCheck(true); 를 다음 코드로 넣어주는 것은 useEffect와 겹쳐보이지만
- 포커스아웃 되었을 시 비동기 통신이 되기 전에 먼저 상태값을 true로 초기화해주는 작업이다.
앞서 했던 조건들로 렌더링
- 이제 회원가입시의 조건을 검사하기 위한 상태들의 설정을 끝냈다.
- idTrim, id, idError, checkIdDupResult이다.
- 코드를 작성할때는
<ErrText>
{idNotice && <span></span>}
{idTrim && !id && <span>필수 입력 정보입니다</span>}
{!idTrim &&
idError &&
!checkIdDupLoading &&
!idNotice &&
checkIdDupResult === (null || true) && (
<span>이메일 형식으로 입력해주세요</span>
)}
{checkIdDupResult &&
!idError &&
!checkIdDupLoading &&
!idNotice && (
// <span style={{ color: blue }}>
// 사용 가능한 이메일입니다
// </span>
<span></span>
)}
{checkIdDupResult === false &&
!idTrim &&
!checkIdDupLoading &&
!idNotice && <span>이미 사용 중인 이메일입니다</span>}
</ErrText>
완료 버튼 클릭시 에러이면 포커스이동
- input의 속성에 ref를 달고 idRef를 설정해놓는다.
- 물론 idRef는 useRef를 사용한 상태이다.
const onSubmit = useCallback(
e => {
e.preventDefault();
if (idError || !id.trim()) {
idRef.current.focus();
return;
}
if (!idDupCheck || passwordError) {
return;
}
dispatch(
__signup({
member_id: id
}),
);
return;
},
[
id,
idError,
passwordEqual,
],
);
- idError라는 상태가 공백이거나, 정규식을 통과 못했을 때 값이 변했던 이유가 여기에 있다.
- 언제 어떻게 값이 공백으로 변할지 모르기에 에러방지를 위해 !id.trim()을 다시 해준다.
- 이후 idRef.current.focus(); 를 통해 공백이거나 에러가 있었다면 서버로 비동기 통신을 보내기전에 참조된 input창으로 포커스를 보내고 return 하여 유저가 회원가입을 올바르게 끝낼 수 있도록 한다.