[React] project part2.

지렁·2023년 11월 23일
0
post-custom-banner

사용할 개념

  • fetch
  • useEffect
  • 페이지네이션
  • 로딩과 에러 처리


import {getData} from './../api'

  • 함수를 바로 export 해오는 경우에는 중괄호를 사용해 함수를 가져와야한다

useEffect로 초기 데이터 가져오기

function App(){
  ...
  const handleLoad = async () => {
    const { reviews } = await getReviews();
    setItems(reviews);
  };

  handleLoad();
  return (
    <>
      <button onClick={() => setOrder("createdAt")}>최신순</button>
      <button onClick={() => setOrder("rating")}>평점순</button>
      <ReviewList items={sortedItems} onDelete={handleDelete}></ReviewList>
    </>
  );
}

위와같이 작성하면 무한루프가 발생한다

왜?

순서를 보면

  • 위에서부터 아래로 실행을 하다가 handLoad 함수를(비동기) 실행하게 되고 html을 그려준다
  • 그와중에 handleLoad는 비동기로 요청보내고, 응답이 도착하면 items를 변경해주게 된다
  • 그러면 state 변경함수로 인해 다시 App 컴포넌트를 실행하게 된다

이럴 때 사용하는 것이 useEffect !

useEffect(() => {
    handleLoad();
  }, []);

이렇게 작성하게 되면
맨 처음 렌더링할 때, 즉 컴포넌트가 mount 될 때 1회만 실행되게 된다
그래서 처음 실행될 때맏 resquest를 보내는 코드가 완성됐다

서버에서 정렬한 데이터 받아오기

초기 데이터를 불러오고 최신순, 베스트 순으로 정렬을 변경해보면 전체 데이터에서 정렬하는 것이 아니라 받아온 데이터 내에서만 정렬한다

이럴경우에는 웹브라우저에서 정렬하는게 아니라 서버에서 정렬된 데이터를 받아와야한다

useEffect로 정렬에 따라 데이터 불러오기

이미 구현된 api를 사용하겠다

평점순

https://learn.codeit.kr/0627/film-reviews?order=rating

최신순

https://learn.codeit.kr/0627/film-reviews?order=createdAt

App.js

const handleLoad = async (queryOrder) => {
const { reviews } = await getReviews(queryOrder);
setItems(reviews);
};

useEffect(() => {
handleLoad(order);
}, [order]);

export async function getReviews(order) {
  // return 필수로 존재해야 한다 !! 없으면 데이터 못불러옴
  return await fetch(`https://learn.codeit.kr/0627/film-reviews?order=${order}`)
    .then((res) => res.json())
    .then((data) => data);
}

페이지네이션

책의 페이지처럼 데이터를 나눠서 제공하는 것

  • 오프셋 기반 : 지금까지 받아온 개수로 계산
    -> 데이터 중복, 누락 발생 가능
  • 커서 기반 : 데이터를 가리키는 값으로(책갈피) 계산
    -> 데이터의 중복이나 누락 없이 가져올 수 있음

렌더링할 때 필요한 정보만 우선 다운받고, 그 후 추가로 데이터 받아오기

구현 순서

api.js에서 offset,limit 파라미터 추가

export async function getReviews({ order, offset, limit }) {
// return 필수로 존재해야 한다 !! 없으면 데이터 못불러옴
return await fetch(
https://learn.codeit.kr/0627/film-reviews?order=${order}&offset=${offset}&limit=${limit}
)
.then((res) => res.json())
.then((data) => data);
}

App.js

const handleLoad = async (option) => {
const { reviews } = await getReviews(option);
if (option.offset === 0) {
setItems(reviews);
} else {
setItems([...items, ...reviews]);
}
setOffset(option.offset + reviews.length);
};

useEffect(() => {
handleLoad({ order, offset, limit: 6 });
}, [order]);
...

return(
...
<button onClick={() => handleLoad({ order, offset, limit: 6 })}>
더보기

profile
공부 기록 공간 🎈💻
post-custom-banner

0개의 댓글