728x90
반응형
목차
참고
전편을 보고 보면 이해에 도움이 됩니다.
https://be-senior-developer.tistory.com/175
defer과 Await, Suspense를 이용한 로딩화면 개선
아래와 같이 데이터가 불러오기전에 네비게이션을 보여주여 사용자의 경험 향상을 시키고 싶을 때가 있다.
import EventsList from "../src/components/EventsList";
import { Suspense } from "react";
import { useLoaderData, json, defer, Await } from "react-router-dom";
function EventsPages() {
const { events } = useLoaderData();
return (
//suspense를 통해 fallback상태에 보여지는 컴포너트 설정
<Suspense fallback={<p style={{ textAlign: "center" }}>Loading...</p>}>
{/* Await를 통해 받아들이는 event를 설정하고 받은 이벤트로 랜더링 하게끔 만듬 */}
<Await resolve={events}>
{(loadedEvents) => <EventsList events={loadedEvents}></EventsList>}
</Await>
</Suspense>
);
}
export default EventsPages;
async function loadEvents() {
const response = await fetch("http://localhost:8080/events");
if (!response.ok) {
console.log(
json(
{ message: "Could not fetch events" },
{
status: 500,
}
)
);
throw json(
{ message: "Could not fetch events" },
{
status: 500,
}
);
} else {
//defer를 거치기 때문에 직접 변환 시켜서 반환해야함
//JSON 본문을 자바스크립트 객체로 변환
const resData = await response.json();
return resData.events;
}
}
export function loader() {
return defer({
events: loadEvents(),
});
}
여러개의 컴포넌트 데이터를 가져올 때 로딩 페이지 핸들링하기
import EventItem from "../src/components/EventItem";
import { Suspense } from "react";
import {
json,
redirect,
useRouteLoaderData,
Await,
defer,
} from "react-router-dom";
import EventsList from "../src/components/EventsList";
function EventDetailPage() {
const { event, events } = useRouteLoaderData("event-detail");
return (
<>
<Suspense fallback={<p style={{ textAlign: "center" }}>loading...</p>}>
<Await resolve={event}>
{(loadedEvent) => <EventItem event={loadedEvent}></EventItem>}
</Await>
</Suspense>
<Suspense fallback={<p style={{ textAlign: "center" }}>loading...</p>}>
<Await resolve={events}>
{(loadedEvents) => <EventsList events={loadedEvents}></EventsList>}
</Await>
</Suspense>
</>
);
}
export default EventDetailPage;
async function loadEvent(id) {
const response = await fetch(`http://localhost:8080/events/` + id);
if (!response.ok) {
throw json(
{ msessage: "Could not fetch details for selected event." },
{
status: 500,
}
);
} else {
const resData = await response.json();
return resData.event;
}
}
async function loadEvents() {
const response = await fetch("http://localhost:8080/events");
if (!response.ok) {
console.log(
json(
{ message: "Could not fetch events" },
{
status: 500,
}
)
);
throw json(
{ message: "Could not fetch events" },
{
status: 500,
}
);
} else {
//defer를 거치기 때문에 직접 변환 시켜서 반환해야함
//JSON 본문을 자바스크립트 객체로 변환
const resData = await response.json();
return resData.events;
}
}
//요청 객체와 parmas를 포함하고 있음
export async function loader({ request, params }) {
const id = params.eventId;
//이런식으로 await를 통해 먼저 로딩해야할 것을 정해 줄 수 있다.
return defer({
event: await loadEvent(id),
events: loadEvents(),
});
}
export async function action({ request, params }) {
const Id = params.eventId;
const response = await fetch(`http://localhost:8080/events/` + Id, {
method: request.method,
});
if (!response.ok) {
throw json(
{ msessage: "Could not fetch details for selected event." },
{
status: 500,
}
);
} else {
return redirect("/events");
}
}
useFetcher를 통한 페이지를 이동하지 않고 데이터 이용하기
우리는 종종 공통된 컴포넌트를 쓰거나 같은 페이지에서 여러번 쓰는 컴포넌트가 있을 수 있다.
그럴때 이동하지 않고 데이터를 받아오기 위해 useFetcher를 사용한다.
import { useEffect } from "react";
import classes from "./NewsLetterSignup.module.css";
import { useFetcher } from "react-router-dom";
function NewsLetterSignup() {
// 공통된 컴포넌트가 있겅나 같은 페이지에서 여러번 사용되는
// 컴포넌트가 있을 경우에 데이터 받을 경우 유용함
const fetcher = useFetcher();
const { data, state } = fetcher;
useEffect(() => {
if (state === "idle" && data && data.message) {
window.alert(data.message);
}
}, [data, state]);
return (
//fetcher.Form은 다른 라우트로의 이동을 막아준다.
<fetcher.Form
method="post"
action="/newsletter"
className={classes.newsletter}
>
<input
type="email"
placeholder="Sign up for newsletter..."
aria-label="Sign up for newsletter"
/>
<button>Sign up</button>
</fetcher.Form>
);
}
export default NewsLetterSignup;
반응형
'코딩 정보 > React' 카테고리의 다른 글
[React] 배포 과정에 대해서 알아보자 (0) | 2024.08.24 |
---|---|
[React] 로그인 시 토큰 기반 인증 만들어보기 (0) | 2024.08.24 |
[React][Router] 라우터 활용을 통한 비동기 통신 (상) (0) | 2024.08.22 |
[React] 통신을 위한 Json과 response, error에 대해 알아보자 (0) | 2024.08.21 |
[React] 라우터의 개념과 활용 방법에 대해 알아보자 (1) | 2024.08.16 |