자식 컴포넌트가 로딩되는 동안 가벼운 대체 컴포넌트(스피너/스켈레톤 등)를 렌더링할 수 있게 해준다.
children : 내가 렌더링하고 싶은 UI. 하지만 만약 이 컴포넌트가 로딩 중이라면 Suspense는 fallback에 들어있는 컴포넌트를 잠시 렌더링한다.fallback : 자식 컴포넌트가 로딩되는 동안 잠시 렌더링될 가벼운 placeholder view, 스피너나 스켈레톤 UI 등useMutation을 사용)//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초 딜레이될 동안 Suspense의 fallback이 렌더링된다.