[ReactNative] React-Query๋กœ ๋ฌดํ•œ์Šคํฌ๋กค ์ ์šฉํ•˜๊ธฐ
728x90

Today, What I learned?

๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฌดํ•œ์Šคํฌ๋กค์„ ์ ์šฉํ•ด ๋ณด์•˜๋‹ค.

๋ฌดํ•œ์Šคํฌ๋กค๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์€ ์•„์ง๊นŒ์ง€ ์‹œ๋„ํ•ด๋ณด์ง€ ๋ชปํ–ˆ๋˜ ๊ธฐ๋Šฅ์ด์—ˆ๋Š”๋ฐ useInfiniteQuery ํ›…์„ ์‚ฌ์šฉํ•ด์„œ ์ƒ๊ฐ๋ณด๋‹ค ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค..!

 

 

FlatList

๋จผ์ € FlatList์—์„œ ๋ฌดํ•œ์Šคํฌ๋กค์„ ์œ„ํ•ด ํ•„์š”ํ•œ ๋‘ ๊ฐ€์ง€ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

 <FlatList
     onEndReached={fetchMoreTopRated}
    onEndReachedThreshold={0.5}
    ... 
 />
  • onEndReached
    ๋์ ์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ ์‹คํ–‰์‹œํ‚ฌ ํ•จ์ˆ˜๊ฐ€ ๋“ค์–ด๊ฐ€๋Š” ์†์„ฑ
  • onEndReachedThreshold
    ์Šคํฌ๋ฆฐ ๋†’์ด์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ์–ผ๋งˆํผ ๋จผ์ € fetch ํ•จ์ˆ˜๋ฅผ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰์‹œํ‚ฌ ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ์†์„ฑ. ์ˆซ์ž๋กœ ๋“ค์–ด๊ฐ„๋‹ค.
    1์ผ ๊ฒฝ์šฐ์—” ๋์— ๋„๋‹ฌํ–ˆ์„ ๊ฒฝ์šฐ ์‹คํ–‰๋œ๋‹ค.

 

๋กœ์ง์˜ ๊ตฌ์„ฑ

๋ฌดํ•œ ์Šคํฌ๋กค์ด ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š”์ง€๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๋ฉด ์ด๋ ‡๋‹ค.

 

๊ธฐ์กด ๋ฐฐ์—ด : [1,2,3,4]
๋ฌดํ•œ ์Šคํฌ๋กค ์‹œ ์ถ”๊ฐ€๋กœ fetch ํ•ด์˜จ ๋ฐฐ์—ด : [5,6,7]

์ƒˆ๋กœ์šด state : [1,2,3,4,5,6,7]

 

state์— ๊ณ„์† ๋ˆ„์ ๋˜์–ด ๊ฐฑ์‹ ๋˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค!
๊ทธ๋Ÿผ ๊ตฌ์ฒด์ ์œผ๋กœ useInfiniteQuery ํ›…์„ ์–ด๋–ป๊ฒŒ ์จ์•ผ ํ•˜๋Š”์ง€ ๋ณด์ž.

 

 

 

useInfiniteQuery

useInfiniteQuery ํ›…์— ํ•„์š”ํ•œ ์ธ์ž๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€๋‹ค.

  • ์ฟผ๋ฆฌํ‚ค
  • fetch ํ•จ์ˆ˜
  • ์˜ต์…˜ ๊ฐ์ฒด (getNextParam๊ฐ€ ๋“ค์–ด๊ฐ)
const {
    data: upcomingData, isLoading, fetchNextPage, hasNextPage} = useInfiniteQuery(['Movies', 'Upcoming'], 
getUpcomingMovies, {
    getNextPageParam: (lastPage) => {
      if (lastPage.page < lastPage.total_pages) {
        return lastPage.page + 1;
      }
    },
  });

์œ„ ์ฝ”๋“œ๊ฐ€ ์ ์šฉํ•œ ์ฝ”๋“œ์ธ๋ฐ ๋ณด๋ฉด ์ด๋ ‡๋‹ค.

 

์ฟผ๋ฆฌํ‚ค

์ฟผ๋ฆฌํ‚ค๋กœ ['Movies', 'Upcoming'] ์ด๋ ‡๊ฒŒ ๋‘ ๊ฐœ๊ฐ€ ๋ฐฐ์—ด๋กœ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค.
๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ์˜ ์ฟผ๋ฆฌ ํ‚ค๋Š” ๋ฐฐ์—ด๋กœ ์—ฌ๋Ÿฌ ๊ฐœ ์ „๋‹ฌํ•ด์ฃผ๊ธฐ๋„ ๊ฐ€๋Šฅ! Movies๋Š” ๋‹ค๋ฅธ useQuery ํ•จ์ˆ˜๋“ค๊ณผ ๊ณต์œ ํ•˜๊ณ  ์žˆ๋Š” ํ‚ค์ด๋‹ค.

 

 

fetch ํ•จ์ˆ˜

์ด์–ด์„œ getUpcomingMovies ๋ผ๋Š” API์™€ ํ†ต์‹ ํ•˜๋Š”, fetch ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์˜ค๊ณ  ์žˆ๋‹ค.

ํ•˜๋‹จ๋ถ€์— ๋‹ฟ์•˜์„ ๊ฒฝ์šฐ ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— pageParam์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์“ด๋‹ค.

์ด ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋Š” ์š”๋Ÿฐ ํ˜•ํƒœ์ด๋‹ค.

{
   "pageParams":[
      "undefined"
   ],
   "pages":[
      {
         "dates":[
            "Object"
         ],
         "page":1,
         "results":[ // ์ง„์งœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ
            "Array"
         ],
         "total_pages":19,
         "total_results":378
      },
          {
         "dates":[
            "Object"
         ],
         "page":2,
         "results":[ // ์ง„์งœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ
            "Array"
         ],
         "total_pages":19,
         "total_results":378
      }
            ...
   ]
}

 

ํ•„์š”ํ•œ ์ •๋ณด๋Š” pages ์†์„ฑ ์•ˆ์˜ ๊ฐ ๊ฐ์ฒด ์† results ๋ถ€๋ถ„์ด๋ผ ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด๋กœ ๋งคํ•‘ํ•˜๋Š” ๊ณผ์ • ํ•„์š”ํ•˜๋‹ค..!

// [{1ํŽ˜์ด์ง€ dates, page...}, {}, {}]
// [[1ํŽ˜์ด์ง€ ์˜ํ™”์ •๋ณด..], [2ํŽ˜์ด์ง€ ์˜ํ™”์ •๋ณด..], []] // ๊ฐ ์š”์†Œ๋ฅผ results ๋ฐฐ์—ด๋กœ ์น˜ํ™˜ 
data.pages.map(page => page.results)

์œ„์™€ ๊ฐ™์ด map์„ ๋Œ๋ ธ์„ ๋•Œ 2์ฐจ์› ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์— flat()์œผ๋กœ ํ‰ํƒ„ํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค!

๊ทธ๋ž˜์„œ ์ตœ์ข…์ ์œผ๋กœ flatList์˜ data ์†์„ฑ์— ๋“ค์–ด๊ฐˆ ์ฝ”๋“œ๋Š” ์ด๋ ‡๋‹ค.

data.pages.map(page => page.results).flat()

 

 

์˜ต์…˜ ๊ฐ์ฒด

๋งˆ์ง€๋ง‰์œผ๋กœ ์˜ต์…˜๊ฐ์ฒด ์•ˆ์—์„œ getNextPageParam์ด๋ผ๋Š” ๊ฐ์ฒด์—์„œ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

getNextPageParam: (lastPage) => {
      if (lastPage.page < lastPage.total_pages) {
        return lastPage.page + 1;
      }
},

์ด ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ์ธ์ž์ธ lastPage๋Š” ์œ„ ๋ฐ์ดํ„ฐ๊ตฌ์กฐ์˜ pages ๊ฐ์ฒด๋‹ค.
pages ๊ฐ์ฒด ์•ˆ์˜ page๊ฐ€ total_page๋ณด๋‹ค ์ž‘์œผ๋ฉด page๋ฅผ 1 ๋”ํ•ด์„œ fetch ํ•จ์ˆ˜๋กœ ๋„˜๊ฒจ์ค€๋‹ค.

 

 

๊ทธ๋Ÿผ ์Šคํฌ๋กค์ด ๋‹ค ๋‚ด๋ ค๊ฐˆ ๋•Œ๋งˆ๋‹ค ์•„๋ž˜์™€ ๊ฐ™์ด ๋ˆ„์ ๋œ๋‹ค.

LOG  {"pageParams": [undefined], "pages": [{"dates": [Object], "page": 1, "results": [Array], "total_pages": 19, "total_results": 378}]}
 LOG  {"pageParams": [undefined], "pages": [{"dates": [Object], "page": 1, "results": [Array], "total_pages": 19, "total_results": 378}]}
 LOG  {"pageParams": [undefined, 2], "pages": [{"dates": [Object], "page": 1, "results": [Array], "total_pages": 19, "total_results": 378}, {"dates": [Object], "page": 2, "results": [Array], "total_pages": 19, "total_results": 378}]}
 LOG  {"pageParams": [undefined, 2], "pages": [{"dates": [Object], "page": 1, "results": [Array], "total_pages": 19, "total_results": 378}, {"dates": [Object], "page": 2, "results": [Array], "total_pages": 19, "total_results": 378}]}
 LOG  {"pageParams": [undefined, 2, 3], "pages": [{"dates": [Object], "page": 1, "results": [Array], "total_pages": 19, "total_results": 378}, {"dates": [Object], "page": 2, "results": [Array], "total_pages": 19, "total_results": 378}, {"dates": [Object], "page": 3, "results": [Array], "total_pages": 19, "total_results": 378}]}

 

 

 

์ตœ์ข…์ ์œผ๋กœ ์ ์šฉํ•˜๋ฉด ์ด๋ ‡๋‹ค!

  <FlatList
      onEndReached={fetchMoreUpcoming}
      onEndReachedThreshold={0.5}
     ...
      data={upcomingData.pages.map((page) => page.results).flat()}
      renderItem={({ item }) => <UpcomingMovieItem movie={item} />}
      keyExtractor={(item) => item.id}
     ...
    />

๋ฆฌ์•กํŠธ ๋„ค์ดํ‹ฐ๋ธŒ์—์„œ ๋ฌดํ•œ์Šคํฌ๋กค์„ ์ ์šฉํ•ด๋ณด์•˜์œผ๋‹ˆ ๋น„์Šทํ•œ ์›๋ฆฌ๋กœ ๋ฆฌ์•กํŠธ์—์„œ๋„ ์ ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค! ๐Ÿค”

728x90