All'alba vincerò

At dawn, I will win!

React

[React] React Router 라이브러리(3) : 데이터 가져오기(Loader) / 데이터 업데이트(Action) / 폼 검증(Form Validation)

나디아 Nadia 2024. 8. 24. 13:19

📌 React Router 라이브러리

  • 프로덕션용으로 사용 가능한 싱글 페이지 앱을 구현(SPA)하기 위한 React Router 라이브러리
  • URL이 변경돼도 싱글페이지로 렌더링 하는 기능을 지원

 


 

☑️ 데이터 가져오기 (Loader)

 loader() 함수

: 특정 라우트가 렌더링되기 전에 데이터를 비동기적으로 로드하는 데 사용

  • 서버에서 데이터를 가져오거나 비동기 작업을 처리한 후 페이지를 렌더링할 수 있도록 한다
  • loader()는 특정 라우트가 활성화되기 전에 필요한 데이터를 미리 로드한다.
    ➡︎ 페이지가 로드될 때 필요한 데이터가 이미 준비되어 있어 사용자에게 빠르게 콘텐츠를 제공한다.
  • 특징
    • 비동기 데이터 로딩
      : loader()는 비동기 함수를 지원하여, 데이터를 비동기적으로 가져올 수 있다.
    • 라우트 기반 데이터 로딩
      : 각 라우트에 대해 데이터를 로딩할 수 있어, 페이지별로 필요한 데이터를 분리하여 관리할 수 있다.
    • 로딩 상태 처리
      : 로딩 중인 상태를 처리할 수 있으며, 로딩 중 또는 에러 상태를 UI에서 표시할 수 있다.

 

 

1. 라우트에 loader 설정

  • createBrowserRouter 또는 createRoutesFromElements에서 loader 함수를 정의한다.
  • 각 라우트에 loader를 추가하여 데이터를 로드한다.
const router = createBrowserRouter([
  {
    element: <Teams />,
    path: "teams",
    // 직접 정의된 loader 함수
    loader: async () => {
      return fakeDb.from("teams").select("*");
    },
    
    children: [
      {
        element: <Team />,
        path: ":teamId",
        // 직접 정의된 loader 함수
        loader: async ({ params }) => {
          return fetch(`/api/teams/${params.teamId}.json`);
        },
      },
    ],
  },
]);

 

loader()

 

 

 

 

⏩ useLoaderData() 훅

: (단일) 라우트의 loader() 함수에서 로드된 데이터를 컴포넌트에서 사용할 수 있게 해준다.

  • useLoaderData()를 통해 컴포넌트는 라우트가 렌더링될 때 미리 로드된 데이터를 쉽게 접근할 수 있다.
  • useLoaderData()는 Router의 loader 함수로부터 반환된 데이터를 가져온다.
    ➡︎ loader 함수는 라우트가 활성화될 때 비동기적으로 데이터를 로드하여 반환한다.
  • 특징
    • 데이터 접근
      : loader 함수에서 반환된 데이터를 컴포넌트에서 간편하게 접근할 수 있다.
    • 비동기 데이터 처리
      : loader와 함께 사용되어 비동기 데이터를 미리 로드하고, 컴포넌트에서 이 데이터를 쉽게 사용할 수 있게 해준다.
    • 라우트 의존성
      : useLoaderData()는 현재 활성화된 라우트의 데이터를 가져오므로, 라우트와 관련된 데이터 로딩을 중앙집중식으로 관리할 수 있다.

 

1. useLoaderData() 불러오기

import { useLoaderData } from 'react-router-dom';

 

 

2. useLoaderData() 훅을 사용하여 현재 라우트에서 로드된 데이터를 컴포넌트에서 사용하기

const teams = useLoaderData();

 

 

 

예제 1. 데이터 로딩과 컴포넌트 렌더링을 분리하여 관리

  • loader 함수로 pb.collection('notes').getList(1, 10)을 호출하여 'notes' 컬렉션에서 1페이지에 10개의 노트를 가져온다.
  • useLoaderData() 훅을 호출하여 라우트의 loader에서 반환된 데이터를 가져온다.
  • data에서 items 배열을 추출하여, 각 아이템의 id와 title을 사용해 리스트를 렌더링한다.
    각 리스트 항목에는 Link 컴포넌트를 사용하여 클릭 시 /notes/${id} 경로로 이동
import pb from '@/api/pb';
import { Link, useLoaderData } from 'react-router-dom';

export function Component() {
  // useLoaderData() 훅을 호출하여 라우트의 loader에서 반환된 데이터를 가져온다.
  const data = useLoaderData();

  return (
    <section id="page">
      <div className="learn">
        <h1>노트 리스트</h1>
        <p>노트 목록을 화면에 렌더링 합니다.</p>

        <ul>
          {/* useLoaderData()를 통해 가져온 데이터 */}
          {data.items.map(({ id, title }) => (
            <li key={id}>
              <Link to={`/notes/${id}`}>{title}</Link>
            </li>
          ))}
        </ul>
      </div>
    </section>
  );
}


// eslint-disable-next-line react-refresh/only-export-components
export const loader = async () => {
  const response = await pb.collection('notes').getList(1, 10);
  return response;
};

// API로부터 받은 응답 데이터를 반환한다.
// 반환된 데이터는 useLoaderData()를 통해 컴포넌트에서 접근할 수 있게 된다.

useLoaderData()

 

 

 

 

⏩ useRouteLoaderData() 훅

: 특정 라우트의 loader() 함수에서 반환된 데이터를 가져오는 데 사용

  • 중첩 라우트 혹은 복잡한 라우트 구조에서 특정 라우트의 데이터를 명시적으로 가져올 수 있다.
  • 특징
    • 명시적 데이터 접근
      : 전체 라우트 트리 내에서 특정 라우트의 로더 데이터를 명시적으로 가져올 수 있다.
    • 중첩 라우트 지원
      : 중첩된 라우트에서 상위 또는 특정 라우트의 데이터를 쉽게 가져올 수 있다.

 

1. useRouteLoaderData() 불러오기

import { useRouteLoaderData } from 'react-router-dom';

 

 

2. 라우터(router)에 id 설정하기 

const router = createBrowserRouter([
  {
    path: 'users', // 경로 설정
    element: <UsersPage />,
    loader: usersLoader, // 로더 설정
    id: 'users', // 라우트 ID 설정
    ],
  },
]);

 

 

3. useRouteLoaderData()를 사용하여 특정 라우트에서 로드된 데이터 가져오기

const users = useRouteLoaderData('라우트의 ID 또는 키');

 

 

 

예제 1. 사용자 목록 컴포넌트

// App 컴포넌트
const router = createBrowserRouter([
  {
    path: 'users',
    element: <UsersPage />,
    loader: usersLoader, // 사용자 목록을 로드하는 로더
    id: 'users', // 라우트 ID 설정
    children: [
      {
        path: ':userId',
        element: <UserDetailPage />,
        loader: userLoader, // 특정 사용자 정보를 로드하는 로더
        id: 'user', // 라우트 ID 설정
      },
    ],
  },
]);


// UsersPage 컴포넌트
function UsersPage() {
  // App.js에서 경로(path)에서 정의한 id를 넣어서 라우트에서 로드된 데이터 가져오기
  const users = useRouteLoaderData('users'); 

  return (
    <div>
      <h1>사용자 목록</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>
            {/* 사용자 상세 페이지로 이동하는 링크 */}
            <Link to={`/users/${user.id}`}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

 

 

 

✨ useLoaderData()  vs  useRouteLoaderData()

  useLoaderData() useRouteLoaderData()
목적 현재 활성화된 라우트의 데이터
접근
특정 라우트 ID의 데이터
명시적 접근
용도 단일 라우트에서
데이터 로딩 및 사용
중첩 라우트나 복잡한 라우트 구조에서
특정 라우트 데이터 접근
데이터
접근 범위
현재 활성화된 라우트의 데이터만 접근 가능 지정한 특정 라우트 ID의 데이터 접근 가능
제한 현재 라우트의 데이터만 사용 가능 특정 라우트 ID에 대한
데이터 접근 필요

 

useRouteLoaderData()

 

 

 

 

⏩ json() 함수

: 서버로부터 받아온 응답을 JSON 형태로 변환하여 반환한다. 

  • 서버로부터의 응답을 JSON 형식으로 변환한다.
  • loader 함수와 함께 사용한다.

 

1. 불러오기

import { json } from "react-router-dom";

 

 

2. loader 함수에 사용하기 

const loader = async () => {
  const data = getSomeData();
  return json(data);
};

 

 

 

예제) 사용자 목록을 로드하는 loader 함수

const usersLoader = async () => {
  const response = await fetch('/api/users'); // 서버로부터 데이터 요청
  if (!response.ok) {
    throw new Error('네트워크 응답에 문제가 있습니다.');
  }
  return json(await response.json()); // JSON으로 변환하여 반환
};

json()

 

 


 

☑️ 데이터 업데이트 (Action)

 action() 함수

: 특정 라우트에서 사용자 상호작용(ex. 폼 제출)으로 발생한 데이터를 서버로 전송하고, 서버의 응답을 처리하는 함수

    • 폼 제출 또는 특정 사용자 작업에 대한 서버 측 작업을 처리 
    • 사용자의 입력을 서버로 전송하고, 서버에서 받은 응답을 바탕으로 클라이언트의 상태를 업데이트하는 데 유용하다.
    • 일반적으로 라우트에서 데이터를 생성, 수정, 삭제하는 작업을 처리한다.
    • 특징
      • 서버 상호작용
        : 클라이언트의 폼 제출이나 기타 작업을 서버로 전송하고, 서버의 응답을 처리한다.
      • 라우트 연결
        : 라우트와 연결되어, 해당 라우트에서의 특정 작업(예: POST 요청)을 처리한다.
      • 비동기 작업 지원
        : 비동기 요청을 지원하여, 서버와의 데이터 전송 및 응답 처리를 비동기적으로 수행할 수 있다.

 

 

1. action() 함수 정의하기

  • 서버와의 상호작용을 정의하는 함수
  • 이 함수는 비동기적으로 데이터를 처리할 수 있다.
export const action = async ({ request }) => {
  const formData = new URLSearchParams(await request.text()); // 폼 데이터 가져오기
  const name = formData.get('name'); // 'name' 필드의 값 추출

  // 서버로 데이터 전송
  const response = await fetch('/api/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name }),
  });

  if (!response.ok) {
    throw new Error('서버에 문제가 발생했습니다.');
  }

  return { success: true }; // 성공 응답 반환
};

 

 

2. 라우터에 action 속성 추가하기

  • 특정 라우트에 action 속성을 추가하여, 해당 라우트의 action() 함수를 설정
const router = createBrowserRouter([
  {
    path: '/',
    element: <FormPage />,
    action: action, // 액션 함수 설정
  },
  {
    path: '/success',
    element: <SuccessPage />,
  },
]);

 

 

3. 폼 제출 및 데이터 처리하기

  • 폼을 제출하거나 작업을 수행하면, action() 함수가 호출된다.
  • 서버로부터의 응답을 처리하여, 클라이언트 상태를 업데이트한다.

 

// FormPage.js
function FormPage() {
  const navigate = useNavigate();

  // 폼 제출 핸들러
  const handleSubmit = (event) => {
    event.preventDefault(); // 폼의 기본 제출 동작 방지
    navigate('/success'); // 성공 페이지로 이동
  };

  return (
    <div>
      <h1>폼 제출</h1>
      <Form method="post" action="/" onSubmit={handleSubmit}>
        <label>
          이름:
          <input type="text" name="name" required />
        </label>
        <button type="submit">제출</button>
      </Form>
    </div>
  );
}

export default FormPage;
// SuccessPage.js
function SuccessPage() {
  return (
    <div>
      <h1>제출 성공!</h1>
      <p>폼이 성공적으로 제출되었습니다.</p>
    </div>
  );
}

export default SuccessPage;

action()

 

 

 

 

⏩ <Form> 컴포넌트
: 폼을 HTML 폼 요소처럼 쉽게 다룰 수 있게 해 주며, 라우터와 함께 사용할 때 폼 제출을 처리하는 데 유용

  • HTML <form> 요소와 유사하지만, 폼 제출 시 페이지 이동과 같은 라우팅 관련 동작을 쉽게 처리할 수 있다.
  • 특징
    • 라우팅 통합
      : 폼 제출 시 자동으로 라우트 이동을 처리할 수 있다.
    • method 및 action 속성
      : HTTP 메서드(GET, POST 등)와 요청 URL을 설정할 수 있다.
    • 폼 상태 관리
      : React Router와 통합되어 폼 상태를 관리하고, 제출 후 리디렉션을 쉽게 처리할 수 있다.
    • 폼 제출 자동 처리
      : 폼 제출을 처리하고, 성공적으로 제출 후 라우트를 업데이트할 수 있다.
  • 속성
    • method
      : 폼 데이터를 서버로 전송할 때 사용할 HTTP 메서드를 지정
      • "get" : 폼 데이터를 URL의 쿼리 문자열로 전송.
        일반적으로 데이터를 조회할 때 사용한다.
      • "post" : 폼 데이터를 요청 본문에 포함하여 전송.
        데이터 생성, 수정, 삭제 등 서버의 상태를 변경하는 요청에 사용된다.
    • action
      : 폼 데이터를 전송할 URL을 지정
      • 속성값: URL 문자열 (절대 경로 또는 상대 경로)
      • 기본값: 현재 URL (window.location.pathname)
    • target
      : 폼 제출 시 결과를 표시할 브라우저 창 or 프레임 지정
      • "_self": 현재 창에서 결과 표시
      • "_blank": 새 창 또는 탭에서 결과 표시
      • "_parent": 부모 프레임에서 결과 표시
      • "_top": 최상위 프레임에서 결과 표시
    • enctype
      : 폼 데이터를 인코딩할 방식을 지정
      • "application/x-www-form-urlencoded": 폼 데이터가 URL 인코딩된 쿼리 문자열 형태로 전송된다. (기본값)
      • "multipart/form-data": 파일 업로드와 같은 복잡한 데이터 전송을 위해 사용된다.
      • "text/plain": 폼 데이터가 텍스트 형태로 전송된다.
<!-- method -->
<Form method="post" action="/submit">
  <input type="text" name="name" />
  <button type="submit">Submit</button>
</Form>

<!-- action -->
<Form method="post" action="/api/submit">
  <input type="text" name="name" />
  <button type="submit">Submit</button>
</Form>

<!-- target -->
<Form method="post" action="/api/submit" target="_blank">
  <input type="text" name="name" />
  <button type="submit">Submit</button>
</Form>

<!-- enctype -->
<Form method="post" action="/api/upload" enctype="multipart/form-data">
  <input type="file" name="file" />
  <button type="submit">Upload</button>
</Form>

 

 

 

1. <Form> 컴포넌트 만들기

  1. Form 가져오기
  2. <Form> 컴포넌트를 사용하여 폼을 정의하고, method, action, onSubmit 등의 속성을 설정한다.
import { Form } from "react-router-dom";

function NewEvent() {
  return (
    <Form method="post" action="/events">
      <input type="text" name="title" />
      <input type="text" name="description" />
      <button type="submit">Create</button>
    </Form>
  );
}

 

 

2. 폼 제출 처리

  • 폼 제출 후 서버와 상호작용하거나 페이지를 업데이트하려면, action 함수와 서버 측 핸들러를 설정해야 한다.
    ➡︎ 폼 제출 시 action 속성에 설정된 URL로 요청이 전송된다.
    ➡︎ 이 때, method 속성을 통해 요청의 타입(POST, GET 등)을 지정할 수 있다.

 

 

예제

// App.js
const router = createBrowserRouter([
  {
    path: '/events',
    element: <NewEvent />,
    action: action, // 액션 함수 설정
  },
  {
    path: '/success',
    element: <SuccessPage />,
  },
]);
// action.js
export const action = async ({ request }) => {
  const formData = new URLSearchParams(await request.text()); // 폼 데이터 가져오기
  const title = formData.get('title');
  const description = formData.get('description');

  // 서버로 데이터 전송
  const response = await fetch('/api/events', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title, description }),
  });

  if (!response.ok) {
    throw new Error('서버에 문제가 발생했습니다.');
  }

  return { success: true }; // 성공 응답 반환
};

<Form>

 

 

 

 

⏩ redirect() 함수

: 사용자가 특정 작업을 완료한 후 다른 페이지로 자동으로 이동시키는 함수

  • 서버나 클라이언트에서 페이지를 다른 URL로 리디렉션할 때 사용
  • 주로 loader()나 action()에서 사용된다.
  • 특징
    • 간편한 리디렉션
      : URL 경로를 간단히 지정하여 클라이언트를 다른 경로로 이동시킬 수 있다.
    • 비동기 작업 후 사용
      : loader나 action 함수에서 비동기 작업(ex. 서버 요청) 후 리디렉션할 때 유용하다.
    • 라우터와 통합
      : React Router와 원활하게 통합되어, 페이지 이동을 쉽게 처리할 수 있다.

 

1. loader() / action()에서 redirect 함수 사용하기

  1. redirect 함수를 가져온온다.
  2. loader 또는 action 함수 내에서 특정 조건을 만족하면, redirect() 함수를 호출하여 페이지를 이동시킨다.
import { redirect } from "react-router-dom";

const loader = async () => {
  const user = await getUser();
  if (!user) {
    return redirect("/login");
  }
  return null;
};

redirect()

 

 

 

 

 useSubmit() 훅

: 폼 제출을 직접적으로 제어할 수 있는 기능

  • <Form> 컴포넌트의 submit 이벤트를 프로그램적으로 트리거할 때 유용하며, 폼 제출을 직접적으로 제어할 수 있다.
  • 폼 제출을 프로그래밍적으로 제어할 수 있는 함수 객체를 반환
    ➡︎ 이 함수 객체를 사용하면 폼 데이터를 비동기적으로 제출하고, 그 결과에 따라 후속 처리를 할 수 있다.
  • 주로 폼이 동적으로 생성되거나 사용자 인터페이스와 직접 상호작용할 때 유용하다.
  • 특징
    • 비동기 제출
      : 폼 데이터를 비동기적으로 제출할 수 있다.
    • 동적 폼 제어
      : 사용자 상호작용에 따라 폼을 직접 제어하고 제출할 수 있다.
    • 폼 상태 관리
      : 제출 후 응답에 따라 상태를 관리하거나 다른 동작을 수행할 수 있다.
    • 속성
      • method
        : 폼 데이터를 서버로 전송할 때 사용할 HTTP 메서드를 지정
        • POST, GET, PUT, DELETE
      • action
        : 폼 데이터를 전송할 URL을 지정
        • 속성값: URL 문자열 (절대 경로 또는 상대 경로)
        • 기본값: 현재 URL (window.location.pathname)
      • enctype
        : 폼 데이터를 인코딩할 방식을 지정
        • "application/x-www-form-urlencoded": 폼 데이터가 URL 인코딩된 쿼리 문자열 형태로 전송된다. (기본값)
        • "multipart/form-data": 파일 업로드와 같은 복잡한 데이터 전송을 위해 사용된다.
        • "text/plain": 폼 데이터가 텍스트 형태로 전송된다.
      • replace
        : 현재 페이지의 히스토리 기록을 대체할지 여부를 설정
        • true ➡︎ 현재 페이지의 히스토리를 새로운 페이지로 대체
        • false ➡︎ 새로운 페이지가 히스토리에 추가
      • headers
        : HTTP 요청 헤더를 설정
        • 제출 요청에 포함될 HTTP 헤더를 설정한다.
        • 서버에서 요구하는 특정 헤더를 추가할 수 있다.
submit(formData, {
  method: 'post', // HTTP 메서드 설정
  action: '/api/submit', // 폼 데이터 전송 URL 설정
  encType: 'application/x-www-form-urlencoded', // 인코딩 방식 설정
  replace: true, // 현재 페이지의 히스토리 대체
  headers: { 'Authorization': 'Bearer token' } // HTTP 헤더 설정
});

 

 

 

1. useSubmit() 훅 가져오기

import { useSubmit, Form } from "react-router-dom";

 

 

2. useSubmit() 사용하여 객체 생성하기

let submit = useSubmit();

 

 

3. <Form>에서 폼 데이터 준비하기

  • 폼 데이터를 수집하거나 생성
<Form
  onChange={(event) => {
    submit(event.currentTarget);<!-- 폼 데이터 준비 -->
  }}
>
  <input type="text" name="search" />
  <button type="submit">Search</button>
</Form>

 

 

3. submit() 함수 호출

  • submit 함수를 호출하여 폼 데이터를 제출
  • 제출 후 결과를 처리

 

submit(formData, { method: 'post', action: '/api/submit' });

 

 

 

예제 1) 폼(Form) 컴포넌트

import React from 'react';
import { useSubmit } from 'react-router-dom';

function FormComponent() {
  const submit = useSubmit(); // useSubmit 훅 사용

  const handleSubmit = (event) => {
    event.preventDefault(); // 기본 폼 제출 동작 방지

    // 폼 데이터 생성
    const formData = new FormData(event.target);

    // submit 함수 호출
    submit(formData, { method: 'post', action: '/api/submit' });
  };


  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>
          이름:
          <input type="text" name="name" required />
        </label>
      </div>
      <div>
        <label>
          이메일:
          <input type="email" name="email" required />
        </label>
      </div>
      <button type="submit">제출</button>
    </form>
  );
}

export default FormComponent;

 

 

예제 2) 폼(Form) 컴포넌트

import { useSubmit, Form } from "react-router-dom";

function SearchField() {
  let submit = useSubmit();
  
  return (
    <Form
      onChange={(event) => {
        submit(event.currentTarget);
      }}
    >
      <input type="text" name="search" />
      <button type="submit">Search</button>
    </Form>
  );
}
import { useSubmit, useLocation } from "react-router-dom";
import { useEffect } from "react";

function AdminPage() {
  useSessionTimeout();
  return <div>{/* ... */}</div>;
}

function useSessionTimeout() {
  const submit = useSubmit();
  const location = useLocation();

  useEffect(() => {
    const timer = setTimeout(() => {
      submit(null, { method: "post", action: "/logout" });
    }, 5 * 60_000);

    return () => clearTimeout(timer);
  }, [submit, location]);
}

useSubmit()

 


 

☑️ 폼 검증 (Form Validation)

⏩ useActionData()

: 폼 제출이나 특정 액션이 발생한 후 서버에서 반환된 데이터를 컴포넌트에서 접근할 수 있도록 해준다.

  • 주로 Router의 action 함수와 함께 사용된다.
  • 특징
    • 폼 제출 후 결과 처리
      : 사용자가 폼을 제출하면, action 함수가 서버로 데이터를 전송하고, 그 결과를 받아온다.
      useActionData는 이 데이터를 가져와 컴포넌트 내에서 활용할 수 있게 해준다.
    • 서버에서 발생한 오류 처리
      : 서버로부터 오류 메시지를 받아와 사용자에게 표시할 때 유용한다.

 

1. action 함수 정의

import { redirect } from 'react-router-dom';

export async function formAction({ request }) {
  const formData = await request.formData(); // 폼 데이터를 가져옴
  const data = Object.fromEntries(formData); // 폼 데이터를 객체로 변환

  // 서버로 데이터 전송 또는 비즈니스 로직 처리
  const response = await fakeApiRequest(data);

  // 성공 시 리다이렉트, 실패 시 오류 메시지 반환
  if (response.ok) {
    return redirect('/success');
  } else {
    return { error: 'Something went wrong!' };
  }
}

 

 

2. 라우터 설정에서 action 함수 연결

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import MyFormComponent from './components/MyFormComponent';
import { formAction } from './actions/formAction';

const router = createBrowserRouter([
  {
    path: '/submit',
    element: <MyFormComponent />,
    action: formAction, // 라우트에 action 함수 연결
  },
]);

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

export default App;

 

 

3. 폼 컴포넌트에서 useActionData 사용

import { useActionData, Form } from 'react-router-dom';

function MyFormComponent() {
  const actionData = useActionData(); // action 함수가 반환한 데이터 가져오기

  return (
    <div>
      <h1>Submit Form</h1>
      <Form method="post" action="/submit"> {/* formAction이 호출될 경로 */}
        <label>
          Name:
          <input type="text" name="name" />
        </label>
        <button type="submit">Submit</button>
      </Form>

      {/* actionData가 존재하면 오류 메시지 출력 */}
      {actionData?.error && <p style={{ color: 'red' }}>{actionData.error}</p>}
    </div>
  );
}

export default MyFormComponent;

 

 

4. Form 컴포넌트 설정

<Form method="post" action="/submit">
  {/* 폼 필드들 */}
</Form>

 

 

5. useActionData()를 통해 반환된 데이터 처리

  • useActionData()를 사용해 action 함수가 반환한 데이터를 컴포넌트에서 접근한다.
  • 이 데이터를 활용해 UI를 업데이트하거나 사용자에게 피드백을 제공할 수 있다.

 

useActionData()