FrontEnd Develop/Project : Fashion Archive

๐Ÿ“š React Query, ๊ณผ์—ฐ ์จ์•ผ ํ•˜๋Š”๊ฐ€? ๊ทธ๋ฆฌ๊ณ  ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น ์นœ์ ˆํ•œ ๋ถ„์„

Frisbeen 2025. 1. 15. 04:11

๐Ÿ” ์„œ๋ก 

React Query๋Š” ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ๋•Œ ๋ฐ์ดํ„ฐ ํŽ˜์นญ, ์บ์‹ฑ, ๋™๊ธฐํ™” ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” **“์™œ React Query๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?”**๋ผ๋Š” ์งˆ๋ฌธ์„ ์‹œ์ž‘์œผ๋กœ, ๊ธฐ์กด ๋ฐฉ์‹๊ณผ React Query ๋ฐฉ์‹์˜ ์ฝ”๋“œ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๊ฐœ์„ ๋œ ๋ถ€๋ถ„์„ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š”, ํŒจ์…˜ ์•„์นด์ด๋ธŒ ํ”„๋กœ์ ํŠธ์—์„œ์˜ ์„œ๋ฒ„ ํ†ต์‹ ์‹œ์— ๊ธฐ์กด์—๋Š” React Query๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ axios๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋ฒ•๊ณผ, 

React Query๋ฅผ ์จ์„œ ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์„ ํ• ๋•Œ์˜ ์ฐจ์ด์ ์„ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ํ•ต์‹ฌ ์ฝ”๋“œ๋งŒ ๋„ฃ๊ฒ ์Šต๋‹ˆ๋‹ค ( ๋ณด์‹œ๋Š” ๋ถ„์˜ ๊ฐ€๋…์„ฑ์„ ์œ„ํ•˜์—ฌ,,)

 

1๏ธโƒฃ ๊ธฐ์กด ์ฝ”๋“œ ๋ฆฌ๋ทฐ

 

๐Ÿ”ง ๊ธฐ์กด ์ฝ”๋“œ (Axios + useEffect ๋ฐฉ์‹)

์„œ๋ฒ„๋Š” JSON ์„œ๋ฒ„๋ฅผ ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

import axios from 'axios';
import { useEffect, useState } from 'react';

const fetchData = () => {
  const [shoes, setShoes] = useState([]);
  const url = `https://codingapple1.github.io/shop/data2.json`;

  useEffect(() => {
    axios
      .get(url)
      .then((response) => setShoes(response.data))
      .catch((error) => console.error('Error fetching data:', error));
  }, []);

  return <ShoeList shoes={shoes} />;
};

 

๐Ÿ‘Ž ๊ธฐ์กด ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ 

1. ์ค‘๋ณต ์ฝ”๋“œ ๋ฐœ์ƒ: ๋ฐ์ดํ„ฐ fetching ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ˜๋ณต๋  ๊ฐ€๋Šฅ์„ฑ์ด ํผ.

2. ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๋ถ€์กฑ: ๋„คํŠธ์›Œํฌ ์žฅ์• ๋‚˜ API ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ ์ฝ”๋“œ๊ฐ€ ํ•„์š”.

3. ์บ์‹ฑ ๋ฏธ์ง€์›: ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์š”์ฒญํ•  ๋•Œ, ๋งค๋ฒˆ ์„œ๋ฒ„์—์„œ ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ด.

4. ๋ฆฌํŒจ์น˜ ๋ฐ ์ƒํƒœ ๋™๊ธฐํ™” ๋ฌธ์ œ: ์ƒˆ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์„ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์•ผ ํ•จ.

 

2๏ธโƒฃ ๊ฐœ์„ ๋œ React Query ์ฝ”๋“œ

 

๐Ÿ”ง React Query ์‚ฌ์šฉ ์ฝ”๋“œ

 

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import ShoeList from './Components/ShoeList';

const fetchShoes = async () => {
  const response = await axios.get(`https://codingapple1.github.io/shop/data2.json`);
  return response.data; // ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜
};

const ShoeListWithReactQuery = () => {
  // useQuery ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ
  const queryResult = useQuery(['shoes'], fetchShoes, {
    staleTime: 1000 * 60 * 5, // 5๋ถ„ ๋™์•ˆ ๋ฐ์ดํ„ฐ๊ฐ€ ์‹ ์„ ํ•˜๋‹ค๊ณ  ๊ฐ„์ฃผ
    cacheTime: 1000 * 60 * 30, // 30๋ถ„ ๋™์•ˆ ์บ์‹œ์— ์œ ์ง€
  });

  // ์ƒํƒœ์— ๋”ฐ๋ผ UI๋ฅผ ๋‹ค๋ฅด๊ฒŒ ๋ณด์—ฌ์ฃผ๊ธฐ
  if (queryResult.isLoading) {
    return <p>Loading...</p>; // ๋กœ๋”ฉ ์ค‘์ผ ๋•Œ
  }

  if (queryResult.isError) {
    return <p>Error fetching shoes.</p>; // ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ
  }

  const shoes = queryResult.data || []; // ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ๋นˆ ๋ฐฐ์—ด๋กœ ์ฒ˜๋ฆฌ

  return (
    <div>
      <button onClick={() => queryResult.refetch()}>์ƒˆ๋กœ๊ณ ์นจ</button>
      <ShoeList shoes={shoes} /> {/* shoes ๋ฐ์ดํ„ฐ๋ฅผ ShoeList ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ */}
    </div>
  );
};

export default ShoeListWithReactQuery;

 

๐Ÿ” ์ฝ”๋“œ ๋ถ„์„

์ฒ˜์Œ ๋ณด๋ฉด ๋Œ€๋ถ€๋ถ„ ์ €๊ฒŒ ๋ญ์ง€ ์‹ถ์„ ๊ฒ๋‹ˆ๋‹ค.

 

1. queryResult๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. 

const queryResult๋Š” useQuery ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

 

ํ•ด๋‹น ๊ฐ์ฒด๋Š” ํฌ๊ฒŒ 4๊ฐ€์ง€ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

queryResult.data → ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ

queryResult.isLoading → ๋กœ๋”ฉ ์ค‘ ์—ฌ๋ถ€

queryResult.isError → ์—๋Ÿฌ ์—ฌ๋ถ€

queryResult.refetch() → ๋ฐ์ดํ„ฐ ์ƒˆ๋กœ๊ณ ์นจ

 

์œ„์˜ 3๊ฐ€์ง€ ๊ธฐ๋Šฅ์€ Boolean ํ˜•ํƒœ๋ฅผ return ํ•˜๋‹ˆ ๋Œ€๊ฐœ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์„ ํ†ตํ•˜์—ฌ ๋กœ๋”ฉ ์ค‘์ธ์ง€, ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์ด ์‹คํŒจํ–ˆ๋Š”์ง€, ์„ฑ๊ณตํ–ˆ๋Š”์ง€๋ฅผ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค.

 

2. ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง

๋กœ๋”ฉ ์ค‘์ผ ๋•Œ "Loading..." ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ "Error fetching shoes." ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

์ •์ƒ์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™”์„ ๊ฒฝ์šฐ ShoeList ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

 

  //{queryResult.data && '์„ฑ๊ณต์ž„'}
  //{queryResult.isLoading && '๋กœ๋”ฉ์ค‘์ž„'}
  //{queryResult.error && '์„ฑ๊ณต์•„๋‹˜'} ๋ญ ์ด๋Ÿฐ์‹์œผ๋กœ ์จ๋„ ๊ดœ์ฐฎ๊ฒ ๋„ค์š”.

 

 

3๏ธโƒฃ React Query ์‚ฌ์šฉ ์‹œ ์ด์ 

 

๐Ÿ‘ ์ฃผ์š” ์žฅ์ 

1. ์บ์‹ฑ ๋ฐ ์žฌ์‚ฌ์šฉ์„ฑ: ๋™์ผํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ค‘๋ณต ์š”์ฒญํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

2. ์ž๋™ ๋ฆฌํŒจ์น˜: ๊ธฐ๋ณธ ์„ค์ •์œผ๋กœ ์ƒˆ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์ž๋™์œผ๋กœ ๋ฆฌํŒจ์น˜๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

3. ์—๋Ÿฌ ๋ฐ ๋กœ๋”ฉ ์ƒํƒœ ๊ด€๋ฆฌ: isLoading, isError ๋“ฑ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋กœ์ง์ด ๊ฐ„๋‹จํ•ด์ง‘๋‹ˆ๋‹ค.

4. ์ž๋™ ์žฌ์‹œ๋„: ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์ผ์ • ํšŸ์ˆ˜๊นŒ์ง€ ์ž๋™์œผ๋กœ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

5. ์ฝ”๋“œ ๊ฐ„์†Œํ™”: useQuery ํ›… ํ•˜๋‚˜๋กœ useState, useEffect, axios ์ฝ”๋“œ๋ฅผ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ์กด ๋ฐฉ์‹ (useEffect + Axios)๊ณผ์˜ ๋น„๊ต

 

๊ธฐ์กด ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ fetchํ•  ๋•Œ๋Š” useState์™€ useEffect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์‹ ๋ฐœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

 

function App() {
  const [shoes, setShoes] = useState([]);

  useEffect(() => {
    axios
      .get('https://codingapple1.github.io/shop/data1.json')
      .then((response) => setShoes(response.data))
      .catch((error) => console.log(error));
  }, []);

  return <ShoeList shoes={shoes} />;
}

 

๋ฐ์ดํ„ฐ ๋กœ๋”ฉ ์ƒํƒœ์™€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์š”์ฒญํ•  ๋•Œ ๋งค๋ฒˆ ์„œ๋ฒ„ ์š”์ฒญ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋„คํŠธ์›Œํฌ ์‹คํŒจ ์‹œ ์ถ”๊ฐ€์ ์œผ๋กœ ์žฌ์‹œ๋„ ๋กœ์ง์„ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๊ฐœ์„ ๋œ React Query ๋ฐฉ์‹

 

React Query๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด useQuery๋ฅผ ํ†ตํ•ด ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ fetching์„ ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ์—” ์ข€ ๋” ํŽธํ•œ๋ฐฉ์‹์ธ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น์„ ํ•˜์—ฌ queryResult ๊ฐ์ฒด๋ฅผ ์ข€ ๋ถ„๋ฆฌํ•ด์„œ ์จ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

const fetchShoes = async () => {
  const { data } = await axios.get('https://codingapple1.github.io/shop/data1.json');
  return data;
};

function App() {
  const { data: shoes = [], isLoading, isError } = useQuery(['shoes'], fetchShoes);

  if (isLoading) return <p>๋กœ๋”ฉ ์ค‘...</p>;
  if (isError) return <p>๋ฐ์ดํ„ฐ ๋กœ๋“œ ์‹คํŒจ</p>;

  return <ShoeList shoes={shoes} />;
}

 

ํฌ๊ฒŒ 3๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ๋Š”๋ฐ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

isLoading, isError๋กœ ๋กœ๋”ฉ ๋ฐ ์—๋Ÿฌ ์ƒํƒœ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.

๋™์ผํ•œ ์š”์ฒญ์— ๋Œ€ํ•œ ์บ์‹ฑ์„ ์ง€์›ํ•˜๋ฏ€๋กœ ๋„คํŠธ์›Œํฌ ๋ถ€๋‹ด์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

 

๊ฒฐ๋ก  ๋‚ด๋ฆฌ๊ธฐ ์ „..๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์ด ๋ฌด์—‡์ธ๊ฐ€?

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์•„์ฃผ ์ค‘์š”ํ•œ ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค. 

ํ•œ๋ฒˆ ์งš๊ณ  ๋„˜์–ด๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค !!!

 

const user = {
  name: 'John Doe',
  age: 30,
  job: 'Developer',
};

 

user๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ์‹œ๋‹ค.

name,age,job์ด๋ผ๋Š” ์†์„ฑ์ด ๋“ค์–ด์žˆ๊ณ  ์šฐ๋ฆฐ ์ด ๊ฐ’์— ์ ‘๊ทผํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์งœ๊ณ ๋Š” ํ•ฉ๋‹ˆ๋‹ค.

const name = user.name; // 'John Doe'
const age = user.age;   // 30
const job = user.job;   // 'Developer'

 

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น ์‚ฌ์šฉํ•˜๊ธฐ ( ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋ฐ–์œผ๋กœ ๋นผ์ž!) 

๋ง ๊ทธ๋Œ€๋กœ ๊ฐ์ฒด์˜ ์†์„ฑ๋ช…์„ {์†์„ฑ๋ช…1, ์†์„ฑ๋ช…2, ์†์„ฑ๋ช…3}  = ๊ฐ์ฒด์ด๋ฆ„ ์œผ๋กœ ๋ป…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ ์†์„ฑ๋ช…1,2,3์„ ๊ฐ์ฒด์˜ ์ ‘๊ทผ๋ฒ•์ธ dot ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ์†์„ฑ์˜ ๊ฐ’์— ์ ‘๊ทผ์„ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const { name, age, job } = user;
console.log(name); // 'John Doe'
console.log(age);  // 30
console.log(job);  // 'Developer'

 

๊ธฐ๋ณธ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

์–ด? ๊ทผ๋ฐ ์œ„์—๋Š” data : shoes = [] ๋‚ฏ์„  ๋ถ€๋ถ„์ด ๋‚˜์™”์Šต๋‹ˆ๋‹ค!

const fetchShoes = async () => {
  const { data } = await axios.get('https://codingapple1.github.io/shop/data1.json');
  return data;
};

function App() {
  const { data: shoes = [], isLoading, isError } = useQuery(['shoes'], fetchShoes);

  if (isLoading) return <p>๋กœ๋”ฉ ์ค‘...</p>;
  if (isError) return <p>๋ฐ์ดํ„ฐ ๋กœ๋“œ ์‹คํŒจ</p>;

  return <ShoeList shoes={shoes} />;
}

์ด ๋ถ€๋ถ„์€ ์—†๋Š” ์†์„ฑ์˜ ๊ฐ’์„ ๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น ํ•˜๊ณ  ์‹ถ์„๋•Œ, ๊ฐ•์ œ๋กœ ๊ฐ’์„ ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

์‰ฌ์šด์˜ˆ์‹œ

const { name, age, job } = user;
console.log(name); // 'John Doe'
console.log(age);  // 30
console.log(job);  // 'Developer'
const { name, gender = 'unknown' } = user;
console.log(name);   // 'John Doe'
console.log(gender); // 'unknown' (๊ฐ์ฒด์— gender ์†์„ฑ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •๋œ ๊ฐ’์ด ์ถœ๋ ฅ๋จ)

์ด์ œ ๊ทธ๋Ÿผ gender๋ผ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ฐ•์ œ๋กœ ๋งŒ๋“  ์†์„ฑ์˜ ๋””ํดํŠธ ๊ฐ’์ธ Unknown์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ gender๋ผ๋Š” ์†์„ฑ์€ user ๊ฐ์ฒด์— ์ถ”๊ฐ€๋˜์—ˆ๋Š”๊ฐ€?

์ฆ‰, ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ ๊ฐ์ฒด ์ž์ฒด์˜ ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚˜๋Š”๊ฐ€?

 

๊ทธ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค! (๋‹คํ–‰์ž…๋‹ˆ๋‹ค)

const user = {
  name: 'John Doe',
  age: 30,
  job: 'Developer',
};

const { name, gender = 'unknown' } = user;

console.log(name);   // 'John Doe'
console.log(gender); // 'unknown'
console.log(user);   // { name: 'John Doe', age: 30, job: 'Developer' }

user ๊ฐ์ฒด๋Š” ์—ฌ์ „ํžˆ { name: 'John Doe', age: 30, job: 'Developer' }์ž…๋‹ˆ๋‹ค.

gender = 'unknown'์€ ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น ์‹œ gender๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ ๊ฒƒ์ผ ๋ฟ user ๊ฐ์ฒด์— ์†์„ฑ์ด ์ถ”๊ฐ€๋œ ๊ฑด ์•„๋‹™๋‹ˆ๋‹ค.

 

์–ต์ง€๋กœ ์†์„ฑ๋ช…(๋ณ€์ˆ˜๋ช…)์„ ์ถ”๊ฐ€ํ•ด์„œ ๊ฐ’์„ ์–ป๊ฒ ๋‹ค ์ •๋„์˜ ์ทจ์ง€์ด์ง€, ๊ฐ์ฒด ์ž์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค!

 

5. useQuery์˜ ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น ์˜ˆ์‹œ

 

๊ทธ๋Ÿผ  ์•„๊นŒ useQuery๋ฅผ ์˜ˆ๋กœ ๋Œ์•„๊ฐ‘์‹œ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ queryResult ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์„œ๋ฒ„์—์„œ ์ด๋Ÿฐ JSON ํ˜•ํƒœ๋ฅผ ํ•˜๋‚˜ ๋ฐ›์•„์™”๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด

const queryResult = {
  data: [{ id: 1, title: 'Shoe 1' }],
  isLoading: false,
  isError: false,
  refetch: () => console.log('๋‹ค์‹œ ๊ฐ€์ ธ์˜ค๊ธฐ!'),
};

 

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ queryResult์˜ ๊ฐ’์„ ๊บผ๋‚ด๊ธฐ

๋งจ๋‚  dot ์—ฐ์‚ฐ์ž๋กœ ์ ‘๊ทผํ•˜๋ฉด props๋ณด๋‚ด๊ธฐ๋„ ๋ถˆํŽธํ•˜๊ณ  ๊ท€์ฐฎ๋‹ค! ์‹ถ์„๋•Œ ์“ฐ๋Š”๊ฒ๋‹ˆ๋‹ค.

์ด์ œ์ฏค ๊ฐ์ด ์˜ค์‹ค๊ฒ๋‹ˆ๋‹ค.

queryResult๋ผ๋Š” ๊ฐ์ฒด์˜ ์†์„ฑ๋“ค์„ queryResult.data ๊ฐ€ ์•„๋‹Œ data!๋กœ๋งŒ ์“ฐ๊ณ  ์‹ถ์€๊ฒ๋‹ˆ๋‹ค.

const { data, isLoading, isError } = queryResult;

console.log(data);      // [{ id: 1, title: 'Shoe 1' }]
console.log(isLoading); // false
console.log(isError);   // false

 

๋ณ€์ˆ˜ ์ด๋ฆ„ ๋ฐ”๊พธ๊ธฐ & ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •

 

์ด์ œ ๋งˆ์ง€๋ง‰ ์ดํ•ด๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. -> ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •(๊ฐ•์ œ ๋ณ€์ˆ˜๋ช… ๋ฐ”๊พธ๊ธฐ)

์ด๋Ÿฐ์‹์œผ๋กœ ๋ง์ž…๋‹ˆ๋‹ค!

const { data: shoes = [], isLoading, isError } = queryResult;

console.log(shoes);     // [{ id: 1, title: 'Shoe 1' }]
console.log(isLoading); // false
console.log(isError);   // false

 

shoes๋Š” [ ] ( ๋นˆ ๋ฐฐ์—ด)๋กœ ์ดˆ๊ธฐํ™”ํ–ˆ๋Š”๋ฐ ์™œ ์ฝ˜์†”์— ์ฐ์œผ๋ฉด ์™œ ๊ฐ’์ด ๋‚˜์˜ค๋Š”๊ฐ€?

์šฐ๋ฆฐ ๋ถ„๋ช… ๋นˆ ๋ฐฐ์—ด๋กœ ๊ฐ’์„ ๊ฐ•์ œํ™” ํ•œ๊ฑฐ ์•„๋‹Œ๊ฐ€?

 

๋งค์šฐ ์ข‹์€ ์งˆ๋ฌธ์ด๊ณ  ํ•„์ž๋„ ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. (ํ—ท๊ฐˆ๋ฆด์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค)

์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ด…์‹œ๋‹ค.

const { data: shoes = [], isLoading, isError } = queryResult;

 shoes = []๋Š” ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ queryResult.data๊ฐ€ undefined ๋˜๋Š” null์ผ ๋•Œ๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, queryResult.data๊ฐ€ undefined์ผ ๋•Œ๋งŒ ๋นˆ ๋ฐฐ์—ด []๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

 

์ฝ”๋“œ ๋™์ž‘ ์›๋ฆฌ

queryResult.data๊ฐ€ ์กด์žฌํ•˜๋ฉด shoes์— queryResult.data์˜ ์‹ค์ œ ๊ฐ’์ด ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

queryResult.data๊ฐ€ undefined์ผ ๊ฒฝ์šฐ shoes์— ๊ธฐ๋ณธ๊ฐ’ []๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

 

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•œ๊ฒƒ์ด์ง€ ๊ฐ•์ œ๋กœ ๋„Œ ๋ฌด์กฐ๊ฑด ๋นˆ ๊ฐ’์ด์•ผ๊ฐ€ ์•„๋‹ˆ๋ž€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’์ด ์ ์šฉ๋˜๋Š” ๊ฒฝ์šฐ

const queryResult = {
  data: undefined, // ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ๋ชปํ–ˆ์„ ๊ฒฝ์šฐ
  isLoading: false,
  isError: true,
};

const { data: shoes = [], isLoading, isError } = queryResult;

console.log(shoes);     // [] (๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋นˆ ๋ฐฐ์—ด ํ• ๋‹น)
console.log(isLoading); // false
console.log(isError);   // true

์œ„์˜ ๊ฒฝ์šฐ queryResult ๊ฐ์ฒด์˜ data ์†์„ฑ์˜ ๊ฐ’์ด undefined์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ data๋ผ๋Š” ์†์„ฑ์„ shoes๋กœ ๋ณ€์ˆ˜๋ช…์„ ๊ฐ•์ œํ™”ํ•˜๊ณ  ํ•ด๋‹น ๊ฐ’์„ [ ] ๋กœ ์ดˆ๊ธฐํ™” ํ–ˆ์„๋•Œ๋Š”

์ƒˆ๋กœ ๋ฐ”๋€ shoes ๋ณ€์ˆ˜๋ช…์€ undefined๋ฅผ ์ค„์ˆ˜๋Š” ์—†์œผ๋‹ˆ [ ] ๋กœ ํ• ๋‹น๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ •๋ฆฌํ•˜๋ฉด

shoes = []๋Š” ๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’์€ queryResult.data๊ฐ€ undefined์ผ ๋•Œ๋งŒ ์ ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์—,

queryResult.data์— ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’ ๋Œ€์‹  ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ queryResult.data์— ๊ฐ’์ด ์žˆ์„ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์€ ๋ฌด์‹œ๋˜๋Š” ๊ฒƒ์ด ์ •์ƒ์ ์ธ ๋™์ž‘์ž…๋‹ˆ๋‹ค.

๋งŒ์•ฝ queryResult.data์— ์‹ค์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์œผ๋ฉด, shoes์—๋Š” ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์€ ๊ฐ’์ด ์—†์„๋•Œ (null or undefined)์ผ๋•Œ๋ฅผ ๋Œ€๋น„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰ ๊ฒฐ๋ก 

React Query๋Š” ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ fetching ๋กœ์ง์ด ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ์ค‘๋ณต๋˜์ง€ ์•Š์œผ๋ฉฐ, ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๋ฐ ๋กœ๋”ฉ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ๋งค์šฐ ๊ฐ„๋‹จํ•ด์ง‘๋‹ˆ๋‹ค.

์บ์‹œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ์ค„์ด๊ณ  ์•ฑ์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์„œ๋ฒ„ ํ†ต์‹ ์ด ๋นˆ๋ฒˆํ•˜๊ฑฐ๋‚˜ ๋งŽ์€ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ผ๋ฉด, React Query๋Š” ํ•„์ˆ˜์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.