728x90

React Router의 loader 속성

들어가며

  • 리액트 라우터(@react-router-dom@)의 @loader@ 속성에 대해 정리해본다.

 

React Router의 @loader@ 속성

  • React Router Version 6 부터 사용할 수 있다.
  • 컴포넌트가 랜더링되기 전에 데이터를 가져올 수 있다.
    • 로더 함수에서 반환된 데이터는 자동으로 해당 컴포넌트에서 사용할 수 있게 된다.
  • 로더는 함수로 정의되며, 해당 함수에서 데이터를 가져와 컴포넌트에 전달한다.
  • 로더 함수를 사용하면 컴포넌트가 렌더링되기 전에 데이터를 가져올 수 있어, 컴포넌트가 초기 로딩 상태를 표시하지 않고 바로 데이터를 렌더링할 수 있다.
    • 따라서 더 나은 사용자 경험을 제공할 수 있다.

 

예제 코드

import { RouterProvider, createBrowserRouter } from "react-router-dom";

import HomePage from "./pages/Home";
import EventsPage from "./pages/Events";
import EventDetailPage from "./pages/EventDetail";
import NewEventPage from "./pages/NewEvent";
import EditEventPage from "./pages/EditEvent";
import RootLayout from "./pages/Root";
import EventsRootLayout from "./pages/EventsRoot";

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      { index: true, element: <HomePage /> }, // path: ""
      {
        path: "events",
        element: <EventsRootLayout />,
        children: [
          {
            index: true,
            element: <EventsPage />,
            loader: async () => {
              const response = await fetch("http://localhost:8080/events");

              if (!response.ok) {
              } else {
                const resData = await response.json();
                return resData.events;
              }
            },
          }, // path: ""
          { path: ":eventId", element: <EventDetailPage /> },
          { path: "new", element: <NewEventPage /> },
          { path: ":eventId/edit", element: <EditEventPage /> },
        ],
      },
    ],
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;

 

  • @loader@를 사용할 경우, 다음과 같이 @Event.js@ 파일에서 데이터를 불러오는 코드를 작성하지 않아도 된다.
import { useEffect, useState } from "react";

import EventsList from "../components/EventsList";

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();
  }, []);
  return (
    <>
      <div style={{ textAlign: "center" }}>
        {isLoading && <p>Loading...</p>}
        {error && <p>{error}</p>}
      </div>
      {!isLoading && fetchedEvents && <EventsList events={fetchedEvents} />}
    </>
  );
}

export default EventsPage;

 

  • 해당 컴포넌트에서 미리 불러온 데이터를 사용하려면 아래와 같이 @useLoaderData@ 를 import 하여 사용한다.
    • @useLoaderData@는 @loader@를 사용하여 데이터를 불러온 컴포넌트와 동일하거나 하위에 있는 컴포넌트에서만 사용할 수 있다. (해당 컴포넌트의 상위 컴포넌트에서는 사용할 수 없다.)
import { useLoaderData } from "react-router-dom";

import EventsList from "../components/EventsList";

function EventsPage() {
  const events = useLoaderData();

  return <EventsList events={events} />;
}

export default EventsPage;

 

 

참고 사이트

 

loader v6.24.0 | React Router

 

reactrouter.com

 

728x90