본문 바로가기
프레임워크&라이브러리/React-Query

[리팩토링] 내 정보 조회 : useEffect => useQuery

by whale in milktea 2023. 7. 13.

참고문헌 :

- https://stackoverflow.com/questions/74095164/switching-out-useeffect-for-tanstack-react-query

- https://gyyeom.tistory.com/125

- https://kyounghwan01.github.io/blog/React/react-query/basic/

- https://tanstack.com/query/v3/docs/react/guides/queries

- 그 외 등등..

이 짧은 수정을 위해, 정말 많은 문서와 github를 뒤졌다..

2가지 핵심요점

1. React-query가 리턴하는 객체
2. Query Key는 뭘까?

React-query가 리턴하는 객체

React-query의 useQuery의 밑바닥 기본형 (필수요소까지 다 제외)

const {} = useQuery([], ()=>{})

이 구문에서 알 수 있듯, useQuery라는 Custom Hook은 결국 배열과 함수를 인자로 전달받아 어떤 데이터들을 리턴하는 Hook이다.

그렇다면, console.log와 같은 간단한 디버깅 도구를 활용하여 이 함수가 리턴하는 값들이 뭔지 파악할 수 있을 것이다. 이제 필수 요소들을 넣어서 구문을 완성해보고, console.log()를 활용하여 데이터들을 확인해보자.

  const { data, isLoading, isError } = useQuery(["memberInfo"], ()=>{
    return getMemberInfo(isLoggedIn);
  })

- data : 서버 요청을 통해 받은 어떤 데이터

- isLoading : 로딩 상태여부를 리턴하는 데이터

- isError : 에러 상태여부를 리턴하는 데이터

 

"React-query에 나와있는 수많은 api들은 어떤 상태를 브라우저에 리턴해주는 값들이고 이 값들을 활용하여 개발자는 특별한 메서드를 활용하여 어떠한 처리를 한다"가 핵심이다.

 

Query-Key란?

react-query를 학습하면서 가장 헷갈렸던 개념이자, useEffect의 의존성 배열과 가장 많이 혼동되었던 개념이다.

useEffect의 의존성 배열과 React-query의 쿼리 키와 혼동되었던 개념을 아래와 같이 정리하고자 한다.

 

React Query는 쿼리 키(query key)를 기반으로 쿼리 캐싱을 관리한다.

- 쿼리 키는 React Query가 데이터를 고유하게 식별하고 캐시하여 중복된 요청을 방지하며, 캐시된 데이터를 재사용할 수 있도록 한다.

- 호출 시점과 데이터 업데이트는 useQuery Hook 내부에서 관리한다.

 

반면, useEffect의 의존성 배열은 해당 배열 내의 값이 변경되면 내부 함수가 실행된다. 이는 데이터 캐싱과는 전혀 관련이 없는 개념이다. - useEffect는 주로 컴포넌트의 라이프사이클이나 특정 값의 변경을 감지하여 효과를 실행하는 데 사용도된다.

 

따라서 React Query의 쿼리 키와 useEffect의 의존성 배열은 서로 다른 목적을 가지고 있다. 쿼리 키는 데이터를 고유하게 식별하고 캐싱하기 위한 것이며, useEffect의 의존성 배열은 효과가 실행되는 조건을 지정하는 데 사용된다.

  • React Query의 쿼리 키는 데이터 식별과 캐싱에 사용
  • useEffect의 의존성 배열은 내부 함수가 실행되는 조건을 지정하는 데 사용

 

리팩토링 전과 후

// 리팩토링 전 코드
import { useEffect } from "react"
const isRendering = useRecoilValue(RenderingState);

 useEffect(() => {
    if (!isLoggedIn) {
      navigate("/login");
    }
    const fetchMemberInfo = async () => {
      try {
        const info = await getMemberInfo(isLoggedIn);
        setMemberInfo(info);
        setIntroduceInfo({ aboutMe: info.aboutMe });
      } catch (error) {}
    };
    fetchMemberInfo();
  }, [isRendering]);
// 리팩토링 후 코드
import { useQuery } from "@tanstack/react-query";

  const { data, isLoading, isError } = useQuery(["memberInfo"], ()=>{
    return getMemberInfo(isLoggedIn);
  })
  const userInfo = data;

  if (!isLoggedIn) navigate("/login");
  if (isLoading) return <div>로딩중...</div>
  if (isError) return <div>에러가 발생했습니다.</div>