์ƒˆ์†Œ์‹

FrontEnd/React

[React] TanStack-Query (React-Query)

  • -

์ด๋ฒˆ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” TanStack Query์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค!_! ํ˜น์‹œ ์•„์ง React Query๋ผ๊ณ  ์•Œ๊ณ  ์žˆ๋Š” ๊ฐ€?! React Query๋Š” 2022๋…„ 8์›”์— TanStack Query๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ React ์™ธ์—๋„ Vue ๋ฐ Svelte์™€ ๊ฐ™์€ ์—ฌ๋Ÿฌ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ง€์›ํ•˜๋„๋ก ํ™•์žฅ๋จ์— ๋”ฐ๋ผ React๋ฅผ ๋„˜์–ด ๋‹ค์–‘ํ•œ ๋ฒ„์ „์„ ํ†ตํ•ฉํ•˜๊ณ  ๋” ๊ด‘๋ฒ”์œ„ํ•œ ๋‹ค์ค‘ ํ”„๋ ˆ์ž„์›Œํฌ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ฐ•์กฐํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ!_! 

 

์•„๋ฌดํŠผ ์ด๋ฒˆ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ํ”„๋กœ์ ํŠธ ์„ค์น˜ ๋ฐ ์…‹ํŒ…๋ฐฉ๋ฒ•๊ณผ tanstack query ์‚ฌ์šฉ ์ด์œ  ๊ทธ๋ฆฌ๊ณ  ์ฃผ์š” ํ•จ์ˆ˜์— ๋Œ€ํ•ด์„œ ์‚ดํŽด๋ณด๊ณ , ๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ์—์„œ tanstack query ์‚ฌ์šฉ๋ฒ•, query ๋™์ž‘ ์ดํ•ด, ๋™์  query ํ•จ์ˆ˜ ๋ฐ query key, ์ฟผ๋ฆฌ ํ™œ์„ฑํ™” ๋น„ํ™œ์„ฑํ™” ๋“ฑ์„ ์ฐจ๋ก€์ฐจ๋ก€ ์ •๋ฆฌํ•ด๋ณด๊ฒ ๋”ฐ!

 

TanStack img
TanStack Query

 


TanStack Query๋Š” React, Vue ๋ฐ Svelte๋ฅผ ํฌํ•จํ•œ ์—ฌ๋Ÿฌ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. ์ตœ์†Œํ•œ์˜ ์ƒ์šฉ๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”, ์บ์‹ฑ ๋ฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹จ์ˆœํ™” ํ•จ. TanStack Query๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ผ๊ด€๋œ API๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์ตœ์‹  ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋‹ค๋ชฉ์ ์ด๊ณ  ํšจ์œจ์ ์ž„.

 

TanStack Query์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์—๋Š” ์ž๋™ ์—…๋ฐ์ดํŠธ ๋ฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์บ์‹œํ•˜๋Š” useMutation๊ณผ ๊ฐ•๋ ฅํ•œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฐ ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ๋กœ ๋ฐ์ดํ„ฐ ์ˆ˜์ •์„ ์ฒ˜๋ฆฌํ•˜๋Š” useMutation์ด ํฌํ•จ ๋จ. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ๋น„๋™๊ธฐ์‹ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜์—ฌ ์ง€์›๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ์ „๋ฐ˜์— ๊ฑธ์ณ ๊ฐ•๋ ฅํ•˜๊ณ  ์ผ๊ด€๋œ API๋ฅผ ์ œ๊ณตํ•จ.

 

๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Œ.

refetch๊ธฐ๋Šฅ๊ณผ ์บ์‹œ์ฒ˜๋ฆฌ๊ฐ€ ํŽธ๋ฆฌ!_! 
์ž๋™ ์บ์‹ฑ, ๋™๊ธฐํ™”, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์ธ๋‹ค๊ทœ!

 

  • React ๋‚ด๋ถ€์—์„œ HTTP ํŽธ๋ฆฌํ•˜๊ฒŒ ์š”์ฒญ ๊ฐ€๋Šฅ
  • ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ์—์„œ ๋ฐฑ์—”๋“œ ์—ฐ๊ฒฐ ํŽธ๋ฆฌ
  • ํ”„๋ก ํŠธ์—”๋“œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ฐฑ์—”๋“œ ๋ฐ์ดํ„ฐ์™€ ๋™๊ธฐํ™”๋œ ์ƒํƒœ๋กœ ์œ ์ง€
    • ๋ฌผ๋ก  ๋ฐ˜๋“œ์‹œ tanstack์ด ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹˜
    • ํ•˜์ง€๋งŒ ์ด์šฉํ•˜๋ฉด ์ฝ”๋“œ ๊ฐ„๊ฒฐํ•˜๊ณ  ํŽธ๋ฆฌ

์ด๋ ‡๊ฒŒ๋งŒ ์‚ดํŽด๋ณด๋ฉด ์•„๋งˆ๋„ fetch ๊ฐ€ ์žˆ๋Š”๋ฐ ์™œ ๊ตณ์ด tanstack-query๋ฅผ ์‚ฌ์šฉํ• ๊นŒ? ๋ผ๋Š” ์˜๋ฌธ์ ์ด ์ƒ๊ธธ ๊ฒƒ์ž„. ์•„๋ž˜์—์„œ fetch์™€ ๋น„๊ต๋ฅผ ํ•˜์—ฌ ์‚ดํŽด๋ณด๊ฒ ์Œ!

 

 

โ–ท fetch์™€ tanstack-query์˜ ๋น„๊ต

(์ฝ”๋“œ) ๊ธฐ์กด์— useEffect์™€ fetch๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์Œ

import { useEffect, useState } from 'react';

import LoadingIndicator from '../UI/LoadingIndicator.jsx';
import ErrorBlock from '../UI/ErrorBlock.jsx';
import EventItem from './EventItem.jsx';

export default function NewEventsSection() {
  const [data, setData] = useState();
  const [error, setError] = useState();
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    async function fetchEvents() {
      setIsLoading(true);
      const response = await fetch('http://localhost:3000/events');

      if (!response.ok) {
        const error = new Error('An error occurred while fetching the events');
        error.code = response.status;
        error.info = await response.json();
        throw error;
      }

      const { events } = await response.json();

      return events;
    }

    fetchEvents()
      .then((events) => {
        setData(events);
      })
      .catch((error) => {
        setError(error);
      })
      .finally(() => {
        setIsLoading(false);
      });
  }, []);

  let content;

  if (isLoading) {
    content = <LoadingIndicator />;
  }

  if (error) {
    content = (
      <ErrorBlock title="An error occurred" message="Failed to fetch events" />
    );
  }

  if (data) {
    content = (
      <ul className="events-list">
        {data.map((event) => (
          <li key={event.id}>
            <EventItem event={event} />
          </li>
        ))}
      </ul>
    );
  }

  return (
    <section className="content-section" id="new-events-section">
      <header>
        <h2>Recently added events</h2>
      </header>
      {content}
    </section>
  );
}

 

  • useEffect ๋‚ด์—์„œ fetch ๋Œ๋ฆฌ๊ณ , useState์˜ data์— ๋‹ด์•„์ฃผ๊ณ , error ๋ž‘isLoading์„ ํ†ตํ•ด์„œ ์ƒํƒœ ํ‘œ์‹œ ํ•ด์ฃผ๊ณ ~ ๋“ฑ
  • ์‚ฌ์‹ค ๋‚˜๋Š” ์œ„ ์ฝ”๋“œ๊ฐ€ ๋” ์ต์ˆ™ํ•˜์ง€๋งŒ, ์ด ์ฝ”๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋งค๋ฒˆ ๊ธด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•จ. ๋ฌผ๋ก  ์ปค์Šคํ…€ ํ›…์œผ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ํ•  ๊ฒฝ์šฐ ์ฝ”๋“œ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ(๋ญ ์˜ˆ๋ฅผ๋“ค๋ฉด useHTTP)
  • ๊ทธ๋ ‡์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ๋“ค์˜ ๋ถ€์กฑํ•จ์ด ์žˆ๋Š”๋ฐ,
    1. ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ํƒญ์œผ๋กœ ์ด๋™ํ•œ ํ›„ ๋‹ค์‹œ ์›น์‚ฌ์ดํŠธ๋กœ ๋Œ์•„์™”์„ ๋•Œ, refetch๊ฐ€ ๋˜์ง€ ์•Š์Œ(๋™์ž‘์„ ํšจ์œจ์  ๊ตฌํ˜„ ์œ„ํ•ด์„œ๋Š” ์ฝ”๋“œ ์ถ”๊ฐ€ ํ•„์š”)
    2. ์บ์‹œ์ฒ˜๋ฆฌ - ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ ์บ์‹œ์ฒ˜๋ฆฌํ•˜๊ณ , ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ ํ›„, ํ•„์š”ํ•  ๋•Œ ๋‹ค์‹œ ์‚ฌ์šฉ

 


https://tanstack.com/query/latest/docs/framework/react/overview

 

Overview | TanStack Query React Docs

TanStack Query (FKA React Query) is often described as the missing data-fetching library for web applications, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your web applications a breeze. Motivation Mo

tanstack.com

 

์œ„์˜ ํ™ˆํŽ˜์ด์ง€์—์„œ latest๋กœ ์„ค์น˜ํ•˜๋ฉด ํŽธ๋ฆฌ

npm i @tanstack/react-query

 

์ฐธ๊ณ ๋กœ 5๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ.

 

 

App() ์ปดํฌ๋„ŒํŠธ์— wrapping

react-query์™€ useQuery ํ›…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  component๋ฅผ tanstack-query๊ฐ€ ์ œ๊ณตํ•˜๋Š” provider component๋กœ ๊ฐ์‹ธ์•ผ ํ•จ.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <RouterProvider router={router} />;
    </QueryClientProvider>
  );
}

 

 


๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์บ์‹œํ•˜์—ฌ ์ž๋™์œผ๋กœ ์„œ๋ฒ„์™€ ๋™๊ธฐํ™”ํ•˜๊ณ  ํ•„์š”์— ๋”ฐ๋ผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์—…๋ฐ์ดํŠธ. ์ˆ˜๋™ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ๋…ผ๋ฆฌ์˜ ํ•„์š”์„ฑ์„ ์ตœ์†Œํ™”ํ•˜์—ฌ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋”์šฑ ๊ฐ„๋‹จํ•˜๊ณ  ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“ฆ.

 

๋‚ด์žฅ๋œ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋ฐ ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ ๋˜๋Š” ์‚ญ์ œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ˆ˜์ •์„ ๊ด€๋ฆฌ. useMutation  ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ž‘์—… ์ค‘์— UI์˜ ์‘๋‹ต์„ฑ๊ณผ ์ผ๊ด€์„ฑ์ด ์œ ์ง€ ๊ฐ€๋Šฅ.

 

์ฟผ๋ฆฌ ๋ฐ ๋ณ€ํ˜•์˜ ๊ตฌ์„ฑ ๋ฐ ๊ด€๋ฆฌ๋ฅผ ์ค‘์•™ ์ง‘์ค‘ํ™”ํ•˜์—ฌ ์ฟผ๋ฆฌ ์บ์‹œ๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณต. ์บ์‹ฑ ์ •์ฑ…, ์ฟผ๋ฆฌ ๋ฌดํšจํ™” ๋ฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ์ „์—ญ ์ œ์–ด๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ๊ฐ€๋Šฅ.

 


 

๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์ธ tanstack-query
์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณด๊ฒ ๋‹ค(useQuery, isPending, isError, error ๋“ฑ)

 

'FrontEnd > React' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

public๊ณผ assets ํด๋”์˜ ์ฐจ์ด์   (1) 2024.06.13
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.