개발자

react query 내에서 과연 react hook을 사용해도 괜찮을까요? 에러 내용을 어떻게 뽑아내면 좋을까요?

2023년 12월 21일조회 540

안녕하세요. 이번에 로그인 시 에러가 날 때, 서버에서 보내주는 각각의 데이터값이 있는데 그것을 추출해서 활용하려고 합니다. 우선 아래 코드와 같이 useMutation (v5) 를 사용했구요. onError 에서 그 값을 추출해서 리턴하고 싶어했습니다. (error 의 타입은 Error 나 AxiosError 하면 해결되는 줄 알았는데, message 값까지 들어가면 타입 정의가 되지 않더라구요.. any를 바꿀 팁도 알려주시면 감사하겠습니다 ㅎ..) (* mutation 의 error의 return 값은 null 로 찍혔습니다..! *) 여튼, 콘솔로 값은 읽을 수 있으나 isError 값이나, error 객체도 원하는 결과값이 나오지 않고, 외부 리턴값으로 활용하는 방법이 떠오르지 않아, 일단 2가지 방법으로 추출을 시도했었습니다. - let 변수를 활용해서 상단에 선언 후에, error 시 재선언하여 값을 입력 - state를 정의하여 setState값으로 입히기 첫번째 방법은 항상 undefined로 읽혀지고, 두번째 방법은 서버 응답 속도에 따라서 값이 받아질 때가 있고, 아닌 경우는 기본 defaultState 값으로 읽혀집니다. 또한, 하나의 hook 내에서 다른 hook 을 선언해버리면 리액트의 훅 규칙을 어기는 것으로 알고 있습니다. 그러기에 위 방법은 옳지 않은 방법인 것 같아서, 옳은 에러 데이터 추출방법을 알고 싶습니다. 감사합니다 :)

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 1

인기 답변

김석현님의 프로필 사진

안녕하세요. 결론: useMutation이 반환하는 error 객체를 사용하셔라. (첨부 코드 참고) 공식 문서 https://tanstack.com/query/latest/docs/react/reference/useMutation 참고하시면 되는데, error 객체에 들어있는 정보는 onError에서 첫 번째 인자로 받은 error 정보와 동일한 것 같군요. 결론과는 별개로 굳이 만약에 react-query에서 error 객체에 접근할 수 있는 인터페이스를 제공하지 않았다고 한다면, state를 정의해서 사용했을 것 같습니다. 관련해서 질문자님께서 "하나의 hook 내에서 다른 hook 을 선언해버리면 리액트의 훅 규칙을 어기는 것으로 알고 있습니다."라고 말씀하셨는데, 이 부분은 다시 한번 생각해 보시면 좋을 것 같아요. usePostLogin라는 커스텀 훅 내에서 const [errorMessage, setErrorMessage] = useState("");를 정의한 게 과연 리액트의 훅 규칙을 어긴 것인가?에 대해서 말입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { useMutation } from '@tanstack/react-query';
import axios from 'axios';

function App() {
  const { mutate: loginMutate, error } = useMutation({
    mutationFn: async () => {
      const response = await axios.post('/api/test');
      const { data } = response;

      return data;
    },
    onSuccess: (data) => {
      console.log(data);
    },
    onError: (error) => {
      // 여기서 받은 error랑 useMutation이 내뱉는 error랑 같음
      console.log(error);
    },
  });

  return (
    <div>
      <button onClick={() => loginMutate()}>로그인</button>
      <p>{error?.message}</p>
    </div>
  );
}

export default App;
김석현님의 프로필 사진

김석현

Software Engineer2023년 12월 21일

근데 본문 다시 보니 error 객체를 뽑아내셨는데 원하는 값이 없었다고 하셨네요?? 좀 잘 이해가 안 되는데, 그럼 어떤 값이 들어있었나요?

이상원님의 프로필 사진

이상원

작성자

Frontend Dev2023년 12월 21일

아. 제가 혼동을 드릴 수 있게 본문에 작성을 했었네요.. Mutation 에서 isError와 error를 객체로 return 하고 사용되는 페이지 컴포넌트에서 뽑아서 console을 찍어봤는데, 각각 false와 null 값을 반환을 해서 그렇게 작성한 것 같습니다. 그리고 답변해주신 커스텀 훅 내의 state 선언 부분은 다시 한번 되짚으며 알아가 보겠습니다. 친절하게 답변주셔서 감사해요. 석현님 :)

김석현님의 프로필 사진

김석현

Software Engineer2023년 12월 21일

맞아요! 처음에는 당연히 null로 찍히는 게 맞는데, 에러 응답을 받은 후에도 동일한가요? 테스트를 위해 1. onError에서 받은 첫 번째 인자의 error를 로그로 찍어본다. 2. usePostLogin 함수 내에서 (return 문 바로 위 정도면 좋겠네요) useMutation이 반환한 error를 로그로 찍어본다. 에러 응답을 받은 후, 두 내용이 다른지 확인해 보면 좋을 것 같습니다.

이상원님의 프로필 사진

이상원

작성자

Frontend Dev2023년 12월 21일

return 문 바로 위에서 console 과 onError 내에서 찍어내는 console 모두 error 객체를 받아냅니다. 하지만 해당 hook을 사용하는 컴포넌트에서는 받아내지를 못합니다. state 값도 error 값도 모두 null이라고 나와요. 아마 제 생각에는 사실 해당 hook 이 다른 mutation의 성공 시, 실행되는 hook이라 미리 정의된 값을 그대로 컴포넌트에서 도출해내는 것 같다는 생각이 듭니다. 컴포넌트 단에서 해당 값이 받아지는 것을 감시해서 값이 들어오면 보여주는 형식으로 구현하면 좋을 것 같아서 한번 해답을 찾아보겠습니다. 점심시간임에도 자세히 봐주셔서 감사합니다!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!