React Query
(지금은 Tanstack Query
가 공식 명칭이지만 React Query로 부르는게 익숙해졌다💦)로 조건부 query를 할 수 있는 방법을 알아본다.
우리 프로젝트에서 사용하는 react query를 이용한 API 훅
프로젝트에서 사용한 useQuery
문의 예시이다.
요약하자면 axios의 get 함수를 정의한 getCheckNotification
함수로 useQuery
문을 작성한 뒤, 훅으로 빼뒀다.
// api/notification.ts
import { useQuery } from "@tanstack/react-query";
// api 함수
const getCheckNotification = async () => {
const response = await axios.get("url");
return response.data;
};
// react query 훅
const useCheckNotification = () => {
const response = useQuery(["check-notification"], getCheckNotification);
return response;
};
export default useCheckPendingStatus;
useQuery
문을 훅으로 빼두면, 실제 이를 호출하는 컴포넌트 / 페이지 단에서 쉽게 사용할 수 있기 때문에 DX가 향상된다는 장점이 있다.
// componenets/GNB.ts
import useCheckNotification from "...";
const GNB = ({
const { data } = useCheckNotification(); // 👈 훅 하나만 호출해서 간편하게 알림 데이터를 get해온다.
return (
...
)
}
export default GNB;
여기서 API를 조건부 호출하려는 이유
위 코드는 현재 진행하고 있는 프로젝트의 GNB 컴포넌트 부분인데, 여기엔 어드민용 / 일반유저용이 따로 렌더링된다.
하지만 완전히 다른 GNB가 아닌, 어드민 유저일 때 알림 컴포넌트를 추가로 렌더링하는 것이었기 때문에 하나의 GNB 컴포넌트를 만들어서 공통적인 부분을 정의하고, 유저가 어떤 타입이냐에 따라 알림 컴포넌트만 추가로 조건부 렌더링을 하는 식이었다.
여기서 문제는 알림 데이터를 받아내기 위해 API 호출을 할 때, 일반유저 계정일 경우 응답으로 403 권한없음 에러
가 발생하기 때문에 어드민 유저일 때만 API 호출을 하고 싶은 상황이다.
try-catch
구문, if 조건문
등등 여러 방법을 시도하려고 했지만 모두 "리액트 훅을 조건부 호출하는 것을 금지한다"라는 룰에 의해 모두 적절한 방법이 아니었다.
그래서 다른 방법이 없을까 하여 구글링으로 더 찾아보니, 스택오버플로우에 나와 같은 고민을 하는 질문글을 찾았고, React Query
자체의 기능으로 의외로 쉽게 해결할 수 있었다.
해결 방법
useQuery
에 제공하는 옵션 중, enabled
를 이용해 조건이 true일 때만 useQuery
훅을 호출할 수 있다.
// react query 훅
const useCheckNotification = (userType: "ADMIN" | "GENERAL") => {
const response = useQuery(["check-notification"], getCheckNotification, {
enabled: userType === "ADMIN", // 👈
});
return response;
};
export default useCheckPendingStatus;
위처럼 query 훅의 파라미터로 userType
을 받도록 하고, enabled
옵션에 userType
이 어드민인지 확인한다.
(참고로 이 쿼리 훅을 호출하는 GNB 컴포넌트에선 현재 로그인한 유저의 타입을 알고 있기 때문에, 이 값을 그대로 쿼리 훅에 파라미터로 전달해주면 된다)
즉, 지금 로그인한 유저가 어드민이라면 이 쿼리 훅이 조건부로 실행되게 할 수 있고, 앞서 발생한 리액트 훅의 조건부 렌더링 금지를 지킬 수 있었다! 👍 (react query 내부적으로 어떻게 작동하는지 신기하다...)
참고 사이트
How to call useQuery hook conditionally?
Because of the Rules of Hooks, one shouldn't call hooks conditionally. So how does one fetch data conditionally using useQuery? For example, let's say I want to fetch data inside a functional compo...
stackoverflow.com
'Front-end > React' 카테고리의 다른 글
[React] React의 불변성 (1) | 2023.11.12 |
---|---|
[React] 드롭다운 헤더 클릭 시 popover 사라지게 만들기 (feat. useOutsideClick) (0) | 2023.08.12 |