React.js

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

녹녹1 2023. 8. 9. 00:24

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 안에서는 최신 상태 값을 가져올 수가 없기 때문에 밖으로 빼두어야 한다는 것이었다.