[React] useQuery + Suspense + setTimeout 으로 fetch 시간 제어하기

박세화·2023년 8월 5일

React JS

목록 보기
20/22

📌 Suspense란?

자식 컴포넌트가 로딩되는 동안 가벼운 대체 컴포넌트(스피너/스켈레톤 등)를 렌더링할 수 있게 해준다.

props

  • children : 내가 렌더링하고 싶은 UI. 하지만 만약 이 컴포넌트가 로딩 중이라면 Suspense는 fallback에 들어있는 컴포넌트를 잠시 렌더링한다.
  • fallback : 자식 컴포넌트가 로딩되는 동안 잠시 렌더링될 가벼운 placeholder view, 스피너나 스켈레톤 UI 등

Suspense


📌 useQuery란?

  • 데이터를 get하기 위한 api이다. (post, update는 useMutation을 사용)
  • 첫 번째 파라미터로 unique key, 두 번째 파라미터로 비동기함수(api 호출 함수)가 들어간다.
  • unique key는 다른 컴포넌트에서도 해당 키를 사용하여 호출할 수 있다.
  • return 값에는 api호출의 성공여부, unique key에 들어있는 데이터값 등이 담긴다.

참고 블로그


🎯 내 프로젝트에 적용

  • Suspense, useQuery, setTimeout 을 사용하여 2초 늦게 데이터를 가져오면서 로딩 화면을 렌더링할 것이다.
//result.component.tsx
export default function Result({ delay }: { delay: number }) {
  const { ctr, ndl, spc } = useSelector(selectOptions);

  const sendToServer = () => {
    const formData = new FormData();
    formData.append("ctr", ctr);
    formData.append("ndl", ndl);
    formData.append("spc", spc);
    return fetch("/pt", {
      method: "POST",
      body: formData,
    });
  };

  const getResult = async ({ delay }: { delay: number }) => {
    await new Promise((resolve) => setTimeout(resolve, delay));
    const res = await sendToServer();
    const data: string | null = await res.json();
    return data;
  };

  const { data } = useQuery(["data"], () => getResult({ delay: delay }), {
    suspense: true,
    cacheTime: 0,
  });

  return (
    <Container className="d-flex flex-column justify-content-center align-items-center mt-5">
      <span className="display-5">{data}</span>
      <Link className="mt-4" to={""}>
        내 위치 근처 맛집 찾아보기
      </Link><br></br>
      <button onClick={onHandleClick}>다시 추천받기</button>
    </Container>
  );
}


//MenuPage.tsx(상위 컴포넌트)
import Result from "../components/result.component";

export default function MenuPage() {
  return (
    <Suspense fallback={<h1>결과를 불러오는 중입니다...</h1>}>
      <Result delay={2000} />
    </Suspense>
  );
}
  • sendToServer : 서버로의 POST 요청을 처리해주는 함수

  • getResult : 서버로부터 데이터를 받아오는 함수이다. setTimeout메소드를 포함하고 있다. 파라미터로 전달되는 delay는 상위 컴포넌트로부터 전달되는 숫자 값이다.

  • useQuery 로 getResult를 호출한다. 리턴 값 내부의 data만 뽑아내어 사용한다.

  • 상위 컴포넌트인 MenuPage 에서 Result 컴포넌트가 2초 딜레이될 동안 Suspensefallback이 렌더링된다.

0개의 댓글