Mutations Without Navigation

김동현·2023년 3월 21일
0

React Router

목록 보기
27/31

지금까지의 모든 mutations는 navigate form을 통해서 이루어 졌다.

이러한 user flow는 일반적이지만, navigation없이 데이터를 변경하는 것도 일반적이다.

이 경우, useFetcher 훅을 이용한다.

이 훅은 navigation없이 loaders 및 actions 와 통신할 수 있도록 해준다.

contact 페이지의 ⭐버튼이 이 경우에 적합하다.

새 레코드를 작성하거나 삭제하는 것도 아니고 페이지를 변경하는 것도 아니다.

현재 페이지의 데이터를 변경하는 것 뿐이다.

Change the "<Favorite>" form to a fetcher form

// 📄src/routes/contact.jsx

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

// existing code

function Favorite({ contact }) {
  const fetcher = useFetcher();
  let favorite = contact.favorite;

  return (
    <fetcher.Form method="post">
      <button
        name="favorite"
        value={favorite ? "false" : "true"}
        aria-label={
          favorite
            ? "Remove from favorites"
            : "Add to favorites"
        }
      >
        {favorite ? "★" : "☆"}
      </button>
    </fetcher.Form>
  );
}

이 폼은 값이 "true" 및 "false" 중 하나인 favorite 키를 사용하여 formData를 전송한다.

method="post" 으로 설정했기 때문에 action 을 호출한다.

<fetcher.Form action="..."> prop이 없어서 랜더링한 route에 post 요청을 한다.

Create the action

// 📄src/routes/contact.jsx

// existing code
import { getContact, updateContact } from "../contacts";

export async function action({ request, params }) {
  let formData = await request.formData();
  return updateContact(params.contactId, {
    favorite: formData.get("favorite") === "true",
  });
}

export default function Contact() {
  // existing code
}

Configure the route's new action

// 📄src/main.jsx

// existing code
import Contact, {
  loader as contactLoader,
  action as contactAction,
} from "./routes/contact";

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    loader: rootLoader,
    action: rootAction,
    children: [
      { index: true, element: <Index /> },
      {
        path: "contacts/:contactId",
        element: <Contact />,
        loader: contactLoader,
        action: contactAction,
      },
      /* existing code */
    ],
  },
]);

사용자 이름 옆에 별 버튼을 클릭할 준비가 완료되었다.
결과 화면

<fetcher.Form method="post"><Form> 과 동일한 동작을 한다.

만약 오류가 발생하더라도 동일하게 동작할 것이다.

다만 한 가지 차이점은, <fetcher.Form method="post"> 는 navigation이 아니란 점이다.

따라서 URL이 바뀌거나 히스토리 스택에 영향을 주지 않는다.

출처 : 리액트 라우터 공식 홈페이지➡️

profile
프론트에_가까운_풀스택_개발자

0개의 댓글