본문 바로가기
React.js

useState + axios (then안에서 많은걸 하려고 하지 말자)

by 녹녹1 2023. 8. 9.

react와 spring boot를 사용해서 이메일 인증을 구현하는 과정에서 버튼을 누르면 emailAuth.do로 api요청이 갔고

response로 인증번호를 받게 해두었다.

 

그런데 입력 하지도 않아도 이렇게 뜨는 상태였다

 

 

코드는 

 // 이메일 인증
  function handleEmailAuth() {
    alert(`${userInfo.email}로 인증번호가 전송되었습니다.`);
    let email = { params: { email: userInfo.email } };
    axios
      .post("http://localhost/clink/user/emailAuth.do", {}, email)
      .then((response) => {
        if (response.data) {
          setAuthcode(response.data.trim());
          if (authcode.trim() === userInfo.emailAuthNum.trim()) {
            setWarningEmail("인증번호가 일치합니다.");
          } else {
            setWarningEmail("인증번호가 일치하지 않습니다.");
          }
        } else {
          setWarningEmail("이메일 인증이 완료되지않았습니다.");
          setUserInfo((prev) => ({
            ...prev,
            email: "",
          }));
        }
      })
      .catch((error) => {
        console.log(error);
        setWarningId("다시 시도하세요");
      });
  }

 

이렇게 되어있었다. 내 짝꿍 짱짱걸 영이한테 물어보니까 response.data를 Authcode에 set시키는 것 까지만 하고 if문을 밖으로 빼보라는 조언을 들었다. 

 

수정한 코드

  useEffect(() => {
    if (userInfo.password !== userInfo.confirmPwd) {
      setWarningPwd("비밀번호가 일치하지 않습니다.");
    } else {
      setWarningPwd("");
    }
    if (authcode.trim() === userInfo.emailAuthNum.trim()) {
      setWarningEmail("인증번호가 일치합니다.");
    } else {
      setWarningEmail("인증번호가 일치하지 않습니다.");
    }
  }, [userInfo.password, userInfo.confirmPwd, userInfo.emailAuthNum, authcode]);

useEffect에서 userInfo.emailAuthNum, authcode값이 바뀔 때 마다 체크하도록 하고 

 function handleEmailAuth() {
    console.log("이메일 주소:" + userInfo.email);
    alert(`${userInfo.email}로 인증번호가 전송되었습니다.`);
    let email = { params: { email: userInfo.email } };
    axios
      .post("http://localhost/clink/user/emailAuth.do", {}, email)
      .then((response) => {
        console.log(response.data);
        if (response.data) {
          setAuthcode(response.data.trim());
        } else {
          setWarningEmail("이메일 인증이 완료되지않았습니다.");
          // setUserInfo((prev) => ({ ...prev, email: "", }));
        }
      })
      .catch((error) => {
        console.log(error);
        setWarningId("다시 시도하세요");
      });
  }

axios에서는 값을 저장만 시키는 걸로 바꿨다

 

 

이제 잘 작동 되었다.

 

왜 그런지 gpt한테 물어보니까

 

위의 두 코드는 조금 다른 동작을 수행합니다.
첫 번째 코드에서는 이메일 인증 번호를 가져와서 `authcode` 상태와 사용자가 입력한 `userInfo.emailAuthNum` 값을 비교한 후 결과에 따라 경고 메시지를 설정합니다.
하지만 `authcode` 상태를 업데이트하는 부분이 `then` 블록 내에 있어서, `authcode` 상태를 최신 값으로 업데이트하기 전에 비교가 이루어집니다.
예를 들어, 인증 번호를 요청하고 `authcode` 상태를 업데이트하기 전에 이미 `useEffect`가 실행되어 사용자가 입력한 `userInfo.emailAuthNum`과 기존 `authcode` 값을 비교할 수 있습니다.그러나 `then` 블록 내에서 `setAuthcode`로 `authcode` 상태를 업데이트하더라도 `useEffect`는 새로운 `authcode` 값으로 다시 실행되지 않습니다.
반면에 두 번째 코드는 `setAuthcode`로 `authcode` 상태를 업데이트한 후에 `useEffect`가 실행되기 때문에 새로운 `authcode` 값으로 `userInfo.emailAuthNum`과 비교하게 됩니다.
따라서 두 번째 코드의 접근 방식이 올바른 것으로 보입니다. `useEffect`를 사용하여 `authcode` 상태 또는 `userInfo.emailAuthNum`이 변경될 때마다 새로운 값을 비교하고 경고 메시지를 설정하는 것이 좋습니다. 이렇게 하면 항상 최신 값으로 비교가 이루어지며, 인증 번호가 일치하는지 정확하게 확인할 수 있습니다.

이렇다는 답을 얻었다.

 

then 안에서는 최신 상태 값을 가져올 수가 없기 때문에 밖으로 빼두어야 한다는 것이었다.

댓글