React는 웹 애플리케이션용 사용자 인터페이스를 구축하는 데 널리 사용되는 자바스크립트 라이브러리입니다. 애플리케이션을 구축할 때는 사용자 상호작용에 따라 브라우저에서 데이터를 적절하게 가져와 렌더링할 수 있도록 효율적인 데이터 관리 방식을 고려하는 것이 중요합니다.

그러나 여러 소스에서 데이터를 가져오고 여러 상태를 지속적으로 업데이트해야 하는 경우 이 프로세스를 관리하는 것은 지루하고 오류가 발생하기 쉬운 작업이 될 수 있습니다. 이러한 경우 Redux 툴킷 쿼리가 효율적인 솔루션을 제공합니다.

Redux 툴킷 쿼리란 무엇인가요?

Redux 툴킷 쿼리 (RTK 쿼리)는 Redux 툴킷을 기반으로 구축된 데이터 가져오기 도구입니다. 공식 문서에서는 RTK Query를 “웹 애플리케이션에서 데이터를 로드하는 일반적인 경우를 단순화하도록 설계된 강력한 데이터 불러오기 및 캐싱 도구로, 데이터 불러오기 및 캐싱 로직을 직접 작성할 필요가 없습니다.”라고 설명합니다.

기본적으로 React 애플리케이션에서 API 또는 기타 데이터 소스에서 데이터를 가져오고 관리하는 프로세스를 간소화하는 일련의 기능을 제공합니다.

Redux 툴킷 쿼리와 React 쿼리 사이에는 유사점이 있지만, Redux 툴킷 쿼리의 주요 장점 중 하나는 상태 관리 라이브러리인 Redux와 원활하게 통합되어 함께 사용할 경우 React 애플리케이션을 위한 완벽한 데이터 가져오기 및 상태 관리 솔루션이 가능하다는 것입니다.

RTK의 핵심 기능에는 데이터 캐싱, 쿼리 관리 기능, 오류 처리 등이 있습니다.

React 애플리케이션에서 Redux 툴킷 쿼리 시작하기

시작하려면 Create React App 명령을 사용하여 로컬에서 React 프로젝트를 빠르게 스핀업할 수 있습니다.

 mkdir React-RTQ
cd React-RTQ
npx create-react-app react-rtq-example
cd react-rtq-example
npm start

또는 웹 애플리케이션을 위한 새로운 빌드 도구이자 개발 서버인 Vite를 사용하여 React 프로젝트를 설정할 수 있습니다.

이 프로젝트의 코드는 이 GitHub 리포지토리에서 찾을 수 있습니다.

필수 종속성 설치

React 프로젝트를 실행하고 나면 다음 패키지를 설치하세요.

 npm install @reduxjs/toolkit react-redux 

API 슬라이스 정의

API 슬라이스는 지정된 API 엔드포인트와 통합하고 상호 작용하는 데 필요한 Redux 로직을 포함하는 컴포넌트입니다. 데이터를 가져오기 위한 쿼리 엔드포인트와 데이터 수정을 위한 변경 엔드포인트를 모두 정의하는 표준화된 방법을 제공합니다.

이 글도 확인해 보세요:  Reqwest로 Rust에서 HTTP 요청 만들기

기본적으로 API 슬라이스를 사용하면 특정 소스의 데이터를 요청하고 변경하기 위한 엔드포인트를 정의할 수 있으므로 API와 통합하는 데 간소화된 접근 방식을 제공합니다.

src 디렉터리에 새 폴더를 만들고 이름을 features로 지정합니다. 이 폴더에 apiSlice.js라는 새 파일을 생성하고 아래 코드를 추가합니다:

 import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

export const productsApi = createApi({
  reducerPath: "productsAp",
  baseQuery: fetchBaseQuery({ baseUrl: "https://dummyjson.com/" }),

  endpoints: (builder) => ({
    getAllProducts: builder.query({
      query: () => "products",
    }),
    getProduct: builder.query({
      query: (product) => `products/search?q=${product}`,
    }),
  }),
});

export const { useGetAllProductsQuery , useGetProductQuery } = productsApi;

이 코드는 Redux 툴킷의 createApi 함수를 사용하여 productsApi라는 API 슬라이스를 정의합니다. API 슬라이스는 다음과 같은 프로퍼티를 사용합니다:

⭐ reducerPath 속성 – Redux 스토어에서 리듀서의 이름을 설정합니다.

⭐ baseQuery 속성 – Redux 툴킷에서 제공하는 fetchBaseQuery 함수를 사용하는 모든 API 요청에 대한 기본 URL을 지정합니다.

⭐ API 엔드포인트 – 빌더 객체를 사용하여 이 API 슬라이스에 사용 가능한 엔드포인트를 지정합니다. 이 경우 코드는 두 개의 엔드포인트를 정의합니다.

마지막으로, 두 개의 엔드포인트를 식별하는 두 개의 후크가 productsAPI 객체에서 생성됩니다. 이 후크를 다양한 React 컴포넌트에서 사용하여 API 요청을 하고, 데이터를 검색하고, 사용자의 상호 작용에 대한 응답으로 상태를 변경할 수 있습니다.

이 접근 방식은 React 애플리케이션에서 상태 관리 및 데이터 불러오기를 간소화합니다.

Redux 스토어 구성

API에서 데이터를 가져온 후 RTK 쿼리는 데이터를 Redux 스토어에 캐시합니다. 이 경우 스토어는 컴포넌트가 필요에 따라 이 데이터에 액세스하고 업데이트할 수 있도록 해당 API 요청에서 검색된 데이터를 포함하여 React 애플리케이션에서 이루어진 API 요청의 상태를 관리하기 위한 중앙 허브 역할을 합니다.

src 디렉터리에 store.js 파일을 생성하고 다음 코드 줄을 추가합니다:

 import { configureStore } from "@reduxjs/toolkit";
import { productsApi } from "./features/apiSlice";

export const store = configureStore({
  reducer: {
   [productsApi.reducerPath]: productsApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
   getDefaultMiddleware().concat(productsApi.middleware),
});

이 코드는 두 가지 주요 구성이 포함된 새 Redux 스토어를 생성합니다:

이 글도 확인해 보세요:  내부에서 REST API 호출을 수행하는 방법 VS 코드

⭐ 리듀서: 스토어가 상태 업데이트를 처리하는 방법을 정의합니다. 이 경우, 제품의 전체 상태 내에서 이를 식별하기 위해 reducer 함수로 productsApi.reducer가 전달되고 고유한 reducerPath 키가 주어집니다.

⭐ 미들웨어: 스토어에 적용해야 하는 추가 미들웨어를 정의합니다.

결과 저장소 개체는 애플리케이션의 상태를 관리하는 데 사용할 수 있는 완전히 구성된 Redux 저장소입니다.

이러한 방식으로 스토어를 구성하면 애플리케이션에서 API 요청의 상태를 쉽게 관리하고 Redux 툴킷을 사용하여 표준화된 방식으로 그 결과를 처리할 수 있습니다.

RTK 기능을 구현할 컴포넌트 생성

src 디렉터리에 새 파일이 들어 있는 새 컴포넌트 폴더를 생성합니다: Data.js.

Data.js 파일에 이 코드를 추가합니다:

 import { useGetAllProductsQuery } from "../features/apiSlice";
import React, { useState } from "react";
import "./product.component.css";

export const Data = () => {
  const { data, error, isLoading, refetch } = useGetAllProductsQuery();
  const [productsData, setProductsData] = useState([]);

  const handleDisplayData = () => {
    refetch();
    setProductsData(data?.products);
  };

  return (
    <div className="product-container">
      <button className="product-button" onClick={handleDisplayData}>
        Display Data
      </button>
      {isLoading && <div>Loading...</div>}
      {error && <div>Error: {error.message}</div>}
      <label className="product-label">Products:</label>
      {productsData && productsData.length > 0 && (
        <ul>
          {productsData.slice(0, 4).map((product) => (
            <li className="product-details" key={product.id}>
              <p>Name: {product.title}</p>
              <p>Description: {product.description}</p>
              <p>Price: {product.price}</p>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

이 코드는 API 슬라이스에서 제공하는 useGetAllProductsQuery 훅을 사용하여 지정된 API 엔드포인트에서 데이터를 검색하는 React 컴포넌트를 보여줍니다.

사용자가 데이터 표시 버튼을 클릭하면 handleDisplayData 함수가 실행되어 제품 데이터를 검색하기 위한 HTTP 요청을 API로 보냅니다. 응답이 수신되면 제품의 데이터 변수가 응답 데이터로 업데이트됩니다. 마지막으로 컴포넌트가 제품 세부 정보 목록을 렌더링합니다.

앱 컴포넌트 업데이트

App.js 파일에서 코드를 다음과 같이 변경합니다:

 import "./App.css";
import { Data } from "./components/Data";
import { store } from "./store";
import { Provider } from "react-redux";
import { ApiProvider } from "@reduxjs/toolkit/query/react";
import { productsApi } from "./features/apiSlice";

function App() {
  return (
    <Provider store={store}>
      <ApiProvider api={productsApi}>
        <div className="App">
          <Data />
        </div>
      </ApiProvider>
    </Provider>
  );
}

export default App;

이 코드는 데이터 컴포넌트를 두 개의 프로바이더로 래핑합니다. 이 두 공급자는 컴포넌트에 Redux 스토어 및 RTK 쿼리 기능에 대한 액세스 권한을 부여하여 API에서 데이터를 가져와 표시할 수 있도록 합니다.

이 글도 확인해 보세요:  Python을 사용하여 할 일 목록 프로그램 만들기

웹 애플리케이션에서 Redux 툴킷 쿼리 사용

최소한의 코드만으로 지정된 소스에서 데이터를 효율적으로 검색하도록 Redux 툴킷 쿼리를 쉽게 구성할 수 있습니다. 또한 API 슬라이스 구성 요소에 변이 엔드포인트를 정의하여 저장된 데이터를 수정하는 함수를 통합할 수도 있습니다.

Redux의 기능과 RTK의 데이터 불러오기 기능을 결합하면 React 웹 애플리케이션을 위한 종합적인 상태 관리 솔루션을 얻을 수 있습니다.

By 최은지

윈도우(Windows)와 웹 서비스에 대한 전문 지식을 갖춘 노련한 UX 디자이너인 최은지님은 효율적이고 매력적인 디지털 경험을 개발하는 데 탁월한 능력을 발휘합니다. 사용자의 입장에서 생각하며 누구나 쉽게 접근하고 즐길 수 있는 콘텐츠를 개발하는 데 주력하고 있습니다. 사용자 경험을 향상시키기 위해 연구를 거듭하는 은지님은 All Things N 팀의 핵심 구성원으로 활약하고 있습니다.