박주니 개발 정리

react-query 적용 본문

react

react-query 적용

박주니 2024. 2. 29. 16:25
728x90
반응형

힌트를 얻게 해준 유튜브 영상

https://www.youtube.com/watch?v=V27XkmVPqYQ

설명전) 노마드코더 20억명 감당한는 법 보면서 api 호출해서 캐싱을 하게되면 먼저 캐싱에 데이터가 있는지 확인하고 있으면 캐싱에서 가져오고 없으면 api 호출하는 방법을 알게되었습니다. 저는 주로 redux에서 해당 유저 정보 데이터 및 관련 데이터만 관리하고 cookie에서는 로그인 상태 확인하는 정도로만 했는데 고민이였던 부분이 중복 api 호출할 경우 서버 부하로도 이어질 수 있기 때문에 어떻게 하면 프론트에서 효율적으로 api 호출 제어할 수 있을 지 찾아보게 되었습니다. 

찾아보는 과정에서 react-query가 지금 과정과 동일한 방법으로 진행한다는 것을 알게되었습니다. 

 

1. react-query를 설치합니다. 

//npm일 경우
npm i react-query
//yarn일 경우
yarn add react-query

 

2. App.js에 react-query import하고 provider을 셋팅합니다. 

import { Route, Routes } from "react-router-dom";
import { CookiesProvider } from "react-cookie";
import { QueryClient, QueryClientProvider } from "react-query";
import UserList from "./Layout/User/_User"; //연결하고자하는 페이지
const queryClient = new QueryClient();
function App(){
	return(
    	<div className="App">
        	 <QueryClientProvider client={queryClient}>
             	<Routes>
                	<Route path="/" element={<UserList/>}></Route>
                </Routes>
             </QueryClientProvider>
        </div>
    )
}

export default App;

추가 설명) UserList는 예시이고 react-query 연결할 페이지를 import하시면 됩니다.  QueryClentProvider이 Routes 상위에 있어야 그 안에 있는 페이지에 react-query 적용이 가능합니다. 

3. react-query 적용할 페이지에 먼저 userQuery를 import합니다. 

import { useQuery } from "react-query";

추가 설명) 저는 UserList.js에 설정을 했으니 UserList.js에 설정을 했습니다. 

4. react-query 설정 기본 구성을 복사해서 붙여놓습니다. 

import React from "react";
import { useQuery } from "react-query";
import axios from "axios";
import qs from "qs";
import { useCookies } from "react-cookie";

// fetchUsers 함수 정의는 그대로 유지됩니다.
const fetchUsers = async (
	// 해당 api에 필요한 매개변수
) => {
  const { data } = await axios.post(
    `연결할 api`,
    qs.stringify({
		// api에 필요한 매개변수 
    }),
    {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
    }
  );

  return data;
};

function UserList() {
  const [cookies] = useCookies(["accessToken"]);
	// api에 필요한 매개변수 

  // useQuery 호출 부분 수정
  const { data, isError, isLoading, error } = useQuery(
    [// api에 필요한 매개변수 셋팅],
    () =>
      fetchUsers(
		// api 필요한 매개변수 
      ),
    {
      onSuccess: (data) => {
        console.log("데이터 불러오기 성공:", data);
        // 성공 로직 추가 위치
      },
      onError: (error) => {
        console.error("데이터 불러오기 에러:", error);
        // 에러 로직 추가 위치
      },
    }
  );

  if (isLoading) return <div>Loading...</div>;
  if (isError) return <div>Error: {error.message}</div>;

  // 데이터 렌더링 로직
  return <div>userlist</div>;
}

export default UserList;

추가 설명)

순서

1. useQuery - 캐시에서 데이터를 고유하게 식별하는 데 사용됩니다. 이 배열에 포함된 값들이 변하면 'useQuery'는 자동으로 해당 데이터를 다시 불러옵니다. useEffect를 사용하지 않고 useQuery가 그 역할을 대신합니다. 

2. fecthUsers- 이 함수명은 각 event에 맞게 변경하시면 됩니다. 이 부분은 data를 가져오는 부분이므로 return data를 하기 위한 부분이라고 생각하시면 됩니다. useQuery에 넣었던 매개변수를 그대로 해당 함수 매개변수에 넣으시면 됩니다. 

3. if (isLoading) return <div>Loading...</div>; - 해당 data를 불러오기 전까지 해당 return안에 있는 html로 나오게 됩니다. 보통은 그자리에 spinner을 적용합니다. 데이터 렌더링이 다 되면 최종 return이 나올 것입니다. 

 

예시 코드 

import React from "react";
import { useQuery } from "react-query";
import axios from "axios";
import qs from "qs";
import { useCookies } from "react-cookie";

// fetchUsers 함수 정의는 그대로 유지됩니다.
const fetchUsers = async (
  page,
  grade,
  type,
  value,
  selectUserType,
  accessToken
) => {
  const { data } = await axios.post(
    `${process.env.REACT_APP_BACKEND_URL}/api/userlist`,
    qs.stringify({
      grade,
      type,
      value,
      page,
      selectUserType,
    }),
    {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json",
        Authorization: `Bearer ${accessToken}`,
      },
    }
  );

  return data;
};

function UserList() {
  const [cookies] = useCookies(["accessToken"]);
  // 기타 필요한 상태 값들
  const currentPage = 1;
  const grade = "all";
  const type = "";
  const value = "";
  const selectUserType = 0;

  // useQuery 호출 부분 수정
  const { data, isError, isLoading, error } = useQuery(
    [currentPage, grade, type, value, selectUserType, cookies.accessToken],
    () =>
      fetchUsers(
        currentPage,
        grade,
        type,
        value,
        selectUserType,
        cookies.accessToken
      ),
    {
      onSuccess: (data) => {
        console.log("데이터 불러오기 성공:", data);
        // 성공 로직 추가 위치
      },
      onError: (error) => {
        console.error("데이터 불러오기 에러:", error);
        // 에러 로직 추가 위치
      },
    }
  );

  if (isLoading) return <div>Loading...</div>;
  if (isError) return <div>Error: {error.message}</div>;

  // 데이터 렌더링 로직
  return <div>userlist</div>;
}

export default UserList;

 

 

728x90
반응형
Comments