함수를 값으로 취하는 프로퍼티 이 페이지를 라우팅하기전에 이 함수를 실행해줌
->loader
안에 데이터를 로딩하고 가져올 수 있음
이전 fetch코드 Event.js
function EventsPage() {
const [isLoading, setIsLoading] = useState(false);
const [fetchedEvents, setFetchedEvents] = useState();
const [error, setError] = useState();
useEffect(() => {
async function fetchEvents() {
setIsLoading(true);
const response = await fetch("http://localhost:8080/events");
if (!response.ok) {
setError("Fetching events failed.");
} else {
const resData = await response.json();
setFetchedEvents(resData.events);
}
setIsLoading(false);
}
fetchEvents();
}, []);
App.js 에서 라우팅할때 loader
이용
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
children: [
{ index: true, element: <HomePage /> },
{
path: "events",
element: <EventsRootLayout />,
children: [
{
index: true,
element: <EventsPage />,
loader: eventsLoader,
},
{ path: ":eventId", element: <EventDetailPage /> },
{ path: "new", element: <NewEventPage /> },
{ path: ":eventId/edit", element: <EditEventPage /> },
],
},
],
},
]);
resData.events
를 리턴하는이유 : 응답 데이터 객체가 실제 이벤트 어레이를 담고잇는 이벤트 프로퍼티를 갖게 되니까Event.js
useloaderData
로 events에 데이터를 삽입
function EventsPage() {
const events = useLoaderData();
return <EventsList events={events} />;
}
export default EventsPage;
export async function loader() {
const response = await fetch("http://localhost:8080/events");
if (!response.ok) {
// ...
} else {
const resData = await response.json();
return resData.events;
}
}
❖ 로딩하려는 위치보다 더 높은 위치에서 데이터를 로딩하면 안됨
loader
를 사용하면 페이지의 초기 렌더링이 완료된 후에 데이터를 가져오는 것이 아니라, 페이지가 로드되는 동안에 데이터를 가져온다.
따라서 UI적으로 로딩을 보여주는게 좋음
usenavigation
state에loading
을 넣어줘 쉽게 처리할 수 있다.
import { Outlet, useNavigation } from "react-router-dom";
import MainNavigation from "../components/MainNavigation";
function RootLayout() {
const navigation = useNavigation();
return (
<>
<MainNavigation />
<main>
{navigation.state === "loading" && <p>,,,,loading</p>}
<Outlet />
</main>
</>
);
}
export default RootLayout;
❖ usestate
같은 리액트 훅은 불가능
function ErrorPage() {
const error = useRouteError();
let title = "An error occurred!";
let message = "Something went wrong!";
if (error.status === 500) {
message = error.data.message;
}
if (error.status === 404) {
title = "Not found!";
message = "Could not find resource or page.";
}
return (
<>
<MainNavigation />
<PageContent title={title}>
<p>{message}</p>
</PageContent>
</>
);
}
export default ErrorPage;
Event.js
if (!response.ok) {
// return { isError: true, message: 'Could not fetch events.' };
throw new Response(JSON.stringify({ message: "Could not fetch events." }), {
status: 500,
});
} else {
return response;
}
}
.data
: HTTP 응답 오류에서는 오류와 관련된 추가적인 정보를 담고 있는 객체
.message
: 오류 객체의 메시지를 나타내는 속성입
error.data.message
는 오류 객체의 데이터에서 메시지를 가져오는 것