[react-query] 클릭했을 때 데이터 fetch하기

김방울·2023년 3월 8일
6

React

목록 보기
3/6

최근 사이드 프로젝트를 하며 react-query 를 공부하는 중입니다.👩‍💻
호출과 동시에 get 요청을 하거나 useMutation 을 사용하여 데이터를 수정하는 예시들은 많은데,
의외로 버튼을 눌렀을 때 get 요청을 보낸다! 의 예시가 잘 보이지 않아 쌩뉴비 입장에서 쪼금.. 난감했습니다 😵

조건이 true일 때 쿼리를 실행하는 옵션이 있다는 것은 알고 있었습니다만
서버에서 받아온 데이터를 useState로 관리하기 싫어서 라이브러리를 쓰는 건데,

쿼리를 불러올 조건을 관리하기 위한 state를 또 만드는 게 맞나? 싶은 생각이 들어서 찾아봤더니 민망할 정도로 간단한 방법이 있었습니다💀 복습하는 겸 블로그에 기록해보았습니다.

react-query?

react-query 는 웹 애플리케이션을 위한 라이브러리로, 서버에서 데이터 가져오기, 캐싱, 데이터 동기화 및 업데이트를 쉽게 만들어줍니다.

react-query 를 사용하지 않고 일반적으로 클라이언트에서 데이터를 fetch하는 방법은 다음과 같습니다.

  type Post = {
    date: string;
    headline: string;
    href: string;
    context?: string;
    tags?: string;
  };

  const [data, setData] = useState<Post[] | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isError, setIsError] = useState(false);

  useEffect(() => {
    (async () => {
      const res = axios.get(YOUR_API_HERE);
      try {
        const resData = await res;
        setData(resData.data);
      } catch (e) {
        console.log(e);
        setIsError(true);
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  useEffect(() => {
    console.log(isLoading, data, isError);
  }, [isLoading, data, isError]);

api 하나 호출하는 것 뿐인데 코드 양이 쓸데없이 장황합니다.😵
같은 내용을 react-query로 바꾸어 fetch해 보겠습니다.

  const { isLoading, data, error } = useQuery('postList', async () => {
    const res = await axios.get(YOUR_API_HERE);
    return res.data;
  });

  useEffect(() => {
    console.log(isLoading, data, error);
  }, [isLoading, data, error]);

isLoading 등의 status를 기본적으로 제공해 주기 때문에,
api 호출 시 loading 상태와 error상태를 따로 바꿔줄 필요가 없어 매우 간결해졌습니다.

이 외에도 다른 창을 포커스했다가 윈도우가 다시 포커스되었을 때, 일정 시간마다 데이터 다시 fetch하기, 동일한 데이터에 대한 여러 요청을 단일 요청으로 중복 제거하기 등등 여러가지 편리한 기능들을 제공해 줍니다.

데이터 fetch 트리거하기

react-query는 호출과 동시에 데이터를 fetch해 옵니다.
그런데 개발하다 보면 마운트됐을 때 뿐만이 아닌, 버튼을 클릭했을 때 데이터를 받아와야 한다던가, 특정 조건이 발동되었을 때 데이터를 받아온다던가...🤤 하는 일이 있습니다.

enabled 옵션

react-query에서 get 요청을 수행하는 역할을 하는 useQuery는 첫번째 파라미터로 쿼리 키 값이, 두번째 파라미터로는 api를 요청하는 함수가, 세번째 파라미터로는 옵션 값이 들어갑니다.

그 중 enabled 라는 옵션이 있는데, 키의 값으로 주어지는 조건이 true 일때만 쿼리를 실행하는 옵션입니다.

const {
  status,
  fetchStatus,
  data: projects,
} = useQuery({
  queryKey: ['projects', userId],
  queryFn: getProjectsByUser,
  enabled: !!userId, // userId가 true 일때만 쿼리 실행
})

값이 false 일 때는 쿼리가 자동으로 실행되지 않으며, 이를 이용해 초기에 자동으로 쿼리가 실행되는 것을 방지할 수 있습니다.

refetch() 로 수동으로 데이터 가져오기

useQuery hook에는 isLoading, isStale, failureCount 같은 다양한 속성이 있습니다. 그 중에 refetch 라는 속성도 있습니다.

refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>

refetch 속성은 쿼리를 수동으로 실행하는 함수입니다.
앞의 enabled 옵션과 같이 사용하면 처음에 선언되었을 때는 데이터 fetch를 하지 않다, 클릭 이벤트가 발생했을 때나 특정 조건에서(state를 따로 또 만들어 주지 않고!) 데이터를 fetch 해올 수 있습니다. 😀

 const { isLoading, data, error, refetch } = useQuery(
    'postList',
    async () => {
      const res = await axios.get(YOUR_API_ADDRESS);
      return res.data;
    },
    {
      enabled: false,
    }
  );

  const onClickButton = () => {
    console.log('데이터를 다시 가져왔어요');
    refetch();
  };

  useEffect(() => {
    console.log(isLoading, data, error);
  }, [isLoading, data, error]);

참고자료

profile
코딩하는 고양이🐱 / UI Developer, Front-end Developer

0개의 댓글

관련 채용 정보