develop

react로 회원가입(3)-중복검사, 조건부 렌더링, 에러시 포커스이동

crab. 2023. 1. 20. 16:09

중복검사

  • 앞서 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 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 하여 유저가 회원가입을 올바르게 끝낼 수 있도록 한다.