React Router의 Loader와 Action

zooyaho·2024년 7월 30일
0
post-thumbnail
post-custom-banner

React Router v6.4부터 loader와 action 기능이 도입되면서 라우트별로 데이터를 로드하고, 폼을 제출하는 등의 작업을 쉽게 처리할 수 있게 되었습니다. 이번 블로그 포스트에서는 loader와 action이 무엇인지, 어떻게 사용하는지, 그리고 실제 예제를 통해 이들의 사용법을 알아보겠습니다.

loader와 action이란?

1. Loader

  • 라우트가 렌더링되기 전에 데이터를 미리 로드하는 기능을 담당합니다.
  • 페이지에 필요한 데이터를 서버나 API로부터 가져와서 렌더링 전에 준비할 수 있습니다.

2. Action

  • 폼 제출 등의 사용자 액션을 처리하는 기능을 담당합니다.
  • 데이터 생성, 수정, 삭제와 같은 작업을 수행하고 그 결과를 라우터로 전달합니다.

3. 예제 코드

먼저 React Router를 설치해야 합니다.

npm install react-router-dom

Loader와 Action 설정

loader와 action을 사용하기 위해서는 라우트를 정의할 때 이들을 설정해주어야 합니다.

import React from 'react';
import {
  BrowserRouter as Router,
  Routes,
  Route,
  useLoaderData,
  useActionData,
  Form
} from 'react-router-dom';

const fetchData = async () => {
  const response = await fetch('https://api.example.com/data');
  return response.json();
};

const postData = async (data) => {
  const response = await fetch('https://api.example.com/data', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  });
  return response.json();
};

const LoaderComponent = () => {
  const data = useLoaderData();
  return (
    <div>
      <h1>Loaded Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
};

const ActionComponent = () => {
  const actionData = useActionData();
  return (
    <div>
      <h1>Form Submission</h1>
      {actionData && <pre>{JSON.stringify(actionData, null, 2)}</pre>}
      <Form method="post">
        <label>
          Name:
          <input type="text" name="name" />
        </label>
        <button type="submit">Submit</button>
      </Form>
    </div>
  );
};

const routes = [
  {
    path: '/load',
    element: <LoaderComponent />,
    loader: fetchData,
  },
  {
    path: '/action',
    element: <ActionComponent />,
    action: async ({ request }) => {
      const formData = await request.formData();
      const data = Object.fromEntries(formData);
      return postData(data);
    },
  },
];

const App = () => (
  <Router>
    <Routes>
      {routes.map((route) => (
        <Route
          key={route.path}
          path={route.path}
          element={route.element}
          loader={route.loader}
          action={route.action}
        />
      ))}
    </Routes>
  </Router>
);

export default App;

loader

  • loader는 라우트가 렌더링되기 전에 데이터를 미리 로드하는 역할을 합니다.
  • 위 예제에서는 /load 경로로 이동할 때 fetchData 함수가 실행되어 API로부터 데이터를 가져옵니다.
  • 이 데이터를 useLoaderData 훅을 사용하여 컴포넌트에서 접근할 수 있습니다.
const LoaderComponent = () => {
  const data = useLoaderData();
  return (
    <div>
      <h1>Loaded Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
};
  • fetchData 함수는 API 호출을 통해 데이터를 가져오고, 이 데이터는 LoaderComponent에서 렌더링됩니다.

action

  • action은 폼 제출 등의 사용자 액션을 처리하는 역할을 합니다.
  • /action 경로로 이동하면 ActionComponent가 렌더링되며, 폼을 제출할 때 postData 함수가 호출되어 데이터를 서버에 전송합니다.
  • useActionData 훅은 라우트 액션 함수가 반환한 데이터를 가져오는 데 사용됩니다

useActionData 훅 사용 목적

  • 폼 제출 후 응답 데이터 접근: 폼이 제출된 후 서버로부터 받은 데이터를 컴포넌트 내에서 접근하고, 이를 렌더링하거나 추가 로직에 사용할 수 있습니다.
  • 사용자 피드백 제공: 폼 제출 후 성공 또는 실패 메시지 등을 사용자에게 보여주는 용도로 사용할 수 있습니다.
const ActionComponent = () => {
  const actionData = useActionData();
  return (
    <div>
      <h1>Form Submission</h1>
      {actionData && <pre>{JSON.stringify(actionData, null, 2)}</pre>}
      <Form method="post">
        <label>
          Name:
          <input type="text" name="name" />
        </label>
        <button type="submit">Submit</button>
      </Form>
    </div>
  );
};
  • postData 함수는 폼 데이터를 서버에 전송하고, 서버의 응답을 받아 ActionComponent에서 표시합니다.
  • 이때 폼 데이터는 input요소의 name 속성에 설정한 값을 key로 하여 구성됩니다.

공식문서

profile
즐겁게 개발하자 쥬야호👻
post-custom-banner

0개의 댓글