티스토리 뷰

- useActionData

가장 최근의 라우트 action에서 직렬화된 데이터를 반환하거나 해당 데이터가 없는 경우에는 undefined를 반환한다.

import type { ActionFunctionArgs } from "@remix-run/node"; // or cloudflare/deno
import { json } from "@remix-run/node"; // or cloudflare/deno
import { Form, useActionData } from "@remix-run/react";

export async function action({
  request,
}: ActionFunctionArgs) {
  const body = await request.formData();
  const name = body.get("visitorsName");
  return json({ message: `Hello, ${name}` });
}

export default function Invoices() {
  const data = useActionData<typeof action>(); // 메세지 데이터 또는 undefined를 할당
  return (
    <Form method="post">
      <input type="text" name="visitorsName" />
      {data ? data.message : "Waiting..."}
    </Form>
  );
}

 

 

 


- 🆕 useAsyncError 

가장 가까운 <Await> 컴포넌트의 거절 값을 반환한다.

import { Await, useAsyncError } from "@remix-run/react";

function ErrorElement() {
  const error = useAsyncError(); // <Await>의 거절(오류)값을 할당
  return (
    <p>Uh Oh, something went wrong! {error.message}</p>
  );
}

<Await
  resolve={promiseThatRejects}
  errorElement={<ErrorElement />}
/>;

 

 

 


- 🆕 useAsyncValue

가장 가까운 상위 <Await> 컴포넌트의 성공 값을 반환한다.

function SomeDescendant() {
  const value = useAsyncValue(); // 상위 <Await>의 성공 값을 할당
  // ...
}


<Await resolve={somePromise}>
  <SomeDescendant />
</Await>

 

 

 


- useBeforeUnload

이 훅은 window.beforeunload 주변의 헬퍼일 뿐이다.

유저가 아직 방문하지 않은 페이지에 대한 링크를 클릭하면 Remix는 해당 페이지에 대한 코드 분할 모듈을 로드한다. 사용자 세션 중간에 배포하거나, 개발자 또는 호스트가 서버에서 이전 파일을 제거하는 경우 해당 모듈에 대한 Remix의 요청은 실패한다.

Remix는 새 URL에서 브라우저를 자동으로 다시 로드하여 복구한다.

이는 최신 버전의 애플리케이션이 있는 서버에서 다시 시작되어야 한다. 대부분의 경우 이는 훌륭하게 작동하며 유저는 무슨 일이 일어났는지조차 모른다.

이 상황에서는 자동 페이지 리로드가 기존 상태를 손실할 수 있기 때문에 브라우저의 로컬 스토리지와 같은 곳에 중요한 애플리케이션 상태를 저장해야 할 수 있다.

 

Remix 여부에 관계없이 이는 좋은 습관이다. 유저는 URL을 변경하거나 실수로 브라우저 창을 닫을 수 있다.

import { useBeforeUnload } from "@remix-run/react";

function SomeForm() {
  const [state, setState] = React.useState(null);

  // save it off before the automatic page reload
  useBeforeUnload(
    React.useCallback(() => {
      localStorage.stuff = state;
    }, [state])
  );

  // read it in when they return
  React.useEffect(() => {
    if (state === null && localStorage.stuff != null) {
      setState(localStorage.stuff);
    }
  }, [state]);

  return <>{/*... */}</>;
}

 

 

 


- useBlocker

사용자가 현재 위치에서 벗어나는 것을 방지하고 사용자 지정 UI를 제공하여 탐색을 확인할 수 있다.

이는 React Router 애플리케이션 내의 클라이언트 측 탐색에만 작동하며 document 요청을 차단하지 않는다.

document 탐색을 방지하려면 자체 'beforeunload' 이벤트 핸들러를 추가해야 한다.

function ImportantForm() {
  const [value, setValue] = React.useState("");

  // 데이터가 input에 들어왔을 때 다른 곳으로의 탐색을 막음
  const blocker = useBlocker(
    ({ currentLocation, nextLocation }) =>
      value !== "" &&
      currentLocation.pathname !== nextLocation.pathname
  );

  return (
    <Form method="post">
      <label>
        Enter some important data:
        <input
          name="data"
          value={value}
          onChange={(e) => setValue(e.target.value)}
        />
      </label>
      <button type="submit">Save</button>

      {blocker.state === "blocked" ? (
        <div>
          <p>Are you sure you want to leave?</p>
          <button onClick={() => blocker.proceed()}>
            Proceed
          </button>
          <button onClick={() => blocker.reset()}>
            Cancel
          </button>
        </div>
      ) : null}
    </Form>
  );
}

 

 

속성

state

blocker의 현재 상태

  • unblocked - blocker가 비어있는 상태이고 탐색을 방해하지 않음
  • blocked - blocker가 탐색을 방해함
  • proceeding - blocker가 차단된 탐색을 통해 진행 중임

 

 

location

blocked 상태에 있을 때, 탐색을 차단한 위치를 나타낸다.

proceeding 상태에 있을 때, blocker.proceed()가 호출된 후 탐색되는 위치이다.

 

 

Methods

proceed()

blocked 상태일 때, blocker.proceed()를 호출해 블록된 위치로 이동할 수 있다.

 

 

reset()

blocked 상태일 때, blocker.reset()을 호출하여 blocker를 unblocked 상태로 되돌리고 유저를 현재 위치에 남겨둘 수 있다.

 

 

 


- useFetcher

탐색 외부에서 서버와 상호작용하기 위한 훅이다.

import { useFetcher } from "@remix-run/react";

export function SomeComponent() {
  const fetcher = useFetcher();
  // ...
}

 

 

옵션

key

기본적으로 해당 컴포넌트로 스코프가 지정된 고유 fetcher를 생성한다.(그러나 진행 중에 useFetcher()에서 조회될 수 있음)

앱의 다른 곳에서 액세스할 수 있도록 자체 key로 fetcher를 식별하고 싶다면, key 옵션을 사용하면 된다.

function AddToBagButton() {
  const fetcher = useFetcher({ key: "add-to-bag" }); // key옵션을 사용해 fetcher에 액세스
  return <fetcher.Form method="post">...</fetcher.Form>;
}


function CartCount({ count }) {
  const fetcher = useFetcher({ key: "add-to-bag" });
  const inFlightCount = Number(
    fetcher.formData?.get("quantity") || 0
  );
  const optimisticCount = count + inFlightCount;
  return (
    <>
      <BagIcon />
      <span>{optimisticCount}</span>
    </>
  );
}

 

 

 

Components

fetcher.Form

탐색을 유발하지 않는다는 점을 제외하면 <Form>과 같다.

function SomeComponent() {
  const fetcher = useFetcher();
  return (
    <fetcher.Form method="post" action="/some/route">
      <input type="text" />
    </fetcher.Form>
  );
}

 

 

 

Methods

fetcher.submit(formData, options)

폼 데이터를 라우트에 제출한다. 여러 개의 중첩 라우트가 URL과 일치할 수 있지만, 리프 라우트만 호출된다.

formData는 여러 유형이 될 수 있다.

  • formData - FormData 인스턴스
  • HTMLFormElement - <form> DOM 요소
  • Object - 기본적으로 FormData 인스턴스로 변환될 key/value 쌍의 객체이다. 더 복잡한 객체를 전달하고 encType: "application/json"을 지정하여 JSON으로 직렬화할 수 있다. 자세한 내용은 useSubmit을 참조!

 

메소드가 GET일 경우, 라우트 loader가 호출되고 formData가 URLSearchParams로 URL에 직렬화된다.

만약 DELETE, PATCH, POST 또는 PUT라면, 라우트 action이 본문으로 formData와 호출된다.

// FormData 인스턴스를 제출 (GET request)
const formData = new FormData();
fetcher.submit(formData);

// HTML 폼 엘리먼트를 제출
fetcher.submit(event.currentTarget.form, {
  method: "POST",
});

// key/value JSON를 FormData 인스턴스로 제출
fetcher.submit(
  { serialized: "values" },
  { method: "POST" }
);

// JSON을 문자열 그대로(raw) 제출
fetcher.submit(
  {
    deeply: {
      nested: {
        json: "values",
      },
    },
  },
  {
    method: "POST",
    encType: "application/json",
  }
);

fetcher.submit는 fetcher 인스턴스에 대한 useSubmit 호출을 둘러싼 랩퍼이므로, useSubmit과 동일한 옵션도 허용한다.

 

 

 

fetcher.load(href, options)

라우트 로더에서 데이터를 로드한다. 여러 개의 중첩 라우트가 URL과 일치할 수 있지만 리프 경로만 호출된다.

fetcher.load("/some/route");
fetcher.load("/some/route?foo=bar");

 

 

 

options.unstable_flushSync

unstable_flushSync 옵션은 React Router DOM이 기본 React.startTransition 대신 ReactDOM.flushSync 호출에서 fetcher.load에 대한 초기 상태 업데이트를 감싸도록 지시한다.

ReactDOM.flushSync는 React 최적화를 해제하고 앱 성능을 저하시킬 수 있다.

 

 

 

 

속성

fetcher.state

fetcher의 상태를 알 수 있다. 상태는 이 중 하나이다.

  • idle - 아무것도 가져오지 않았음
  • submitting - 폼이 제출되었음. 메소드가 GET이라면 라우트 loader가 호출됨. 메소드가 DELETE, PATCH, POST, PUT이라면 라우트 action이 호출됨
  • loading - action 제출 이후에 라우트에 대한 로더들이 리로드됨

 

 

fetcher.data

action 또는 loader에서 반환된 응답 데이터가 여기에 저장된다. 데이터가 설정되면 다시 로드하고 다시 제출하는 경우에도(예: 이미 데이터를 읽은 후 다시 fetcher.load()를 호출하는 경우) fetcher에서 유지된다.

 

 

fetcher.formData

서버에 제출된 FormData 인스턴스가 여기에 저장된다. 이는 낙관적 UI에 유용하다.

 

 

fetcher.formAction

제출물의 URL이다.

 

 

fetcher.formMethod

제출물의 폼 메소드이다.

 

 

 


- useFetchers

진행중인 모든 fetcher들의 배열을 반환한다.

fetcher를 생성하지 않았지만 낙관적 UI에 참여하기 위해 제출물을 사용하길 원하는 앱의 전체적인 컴포넌트에 유용하다.

import { useFetchers } from "@remix-run/react";

function SomeComponent() {
  const fetchers = useFetchers();
  fetchers[0].formData; // FormData
  fetchers[0].state; // etc.
  // ...
}

fetchers는 fetcher.Form, fetcher.submit, fetcher.load를 포함하지 않고, 오직 fetcher.formData, fetcher.state와 같은 상태만 포함한다.

 

 

 


- useFormAction

앱의 현재 URL 대신 컴포넌트 계층 구조에 있는 가장 가까운 경로에 대한 URL을 확인한다.

가장 가까운 경로에 대한 action을 해결하기 위해 <Form>에서 내부적으로 사용되지만 일반적으로 사용할 수도 있다.

import { useFormAction } from "@remix-run/react";

function SomeComponent() {
  // 가장 가까운 라우트 URL
  const action = useFormAction();

  // 가장 가까운 라우트 URL + "destroy"
  const destroyAction = useFormAction("destroy");
}

 

 

Signature

useFormAction(action, options)

 

action

선택 항목. 가장 가까운 라우트 URL에 추가할 action

 

options

유일한 옵션은 { relative: "route" | "path"}이다.

  • route 기본값 - URL이 아닌 라우트 계층 구조를 기준으로 함
  • path - URL 경로를 기준으로 action을 수행하므로 ..이 하나의 URL 세그먼트를 지울 것임

 

 

 

 


- useHref

link에 대한 href로 사용할 현재 위치에 대한 전체 URL을 확인한다.

상대 경로가 제공되면 전체 URL로 확인된다.

import { useHref } from "@remix-run/react";

function SomeComponent() {
  const href = useHref("some/where");

  return <a href={href}>Link</a>;
}

 

 

Signature

useHref(to, options)

 

to

선택 항목. 확인된 URL에 추가할 경로

 

options

유일한 옵션은 { relative: "route" | "path"}이며 상대 URL을 확인할 때의 동작을 정의하는 것이다.

  • route 기본값 - URL이 아닌 라우트 계층 구조를 기준으로 함
  • path - URL 경로를 기준으로 action을 수행하므로 ..이 하나의 URL 세그먼트를 지울 것임

 

 

 

 


- useLoaderData

가장 가까운 라우트 loader에서 직렬화된 데이터를 반환한다.

import { json } from "@remix-run/node"; // or cloudflare/deno
import { useLoaderData } from "@remix-run/react";

export async function loader() {
  return json(await fakeDb.invoices.findAll());
}

export default function Invoices() {
  const invoices = useLoaderData<typeof loader>();
  // ...
}

 

 

 


- useLocation

현재 위치 객체를 반환한다.

import { useLocation } from "@remix-run/react";

function SomeComponent() {
  const location = useLocation();
  // ...
}

 

 

Properties

location.hash

현재 URL의 해시

 

location.key

이 위치의 고유 키

 

location.pathname

현재 URL의 경로

 

location.search

현재 URL의 쿼리 문자열

 

location.state

<Link state> 또는 navigate에 의해 생성된 위치의 상태 값

 

 

 


- useMatches

현재 라우트가 페이지에서 일치하는 지를 반환한다.

이는 현재 라우트로 레이아웃 추상화를 만드는 데 유용하다.

function SomeComponent() {
  const matches = useMatches();

  // ...
}

 

matches는 다음과 같은 형상을 띈다.

[
  { id, pathname, data, params, handle }, // root route
  { id, pathname, data, params, handle }, // layout route
  { id, pathname, data, params, handle }, // child route
  // etc.
];

 

 

 

 


- useNavigate

유저 상호작용이나 이펙트에 응답하여 브라우저에서 프로그래밍 방식으로 탐색할 수 있는 함수를 반환한다.

import { useNavigate } from "@remix-run/react";

function SomeComponent() {
  const navigate = useNavigate();
  return (
    <button
      onClick={() => {
        navigate(-1);
      }}
    />
  );
}

종종 action이나 loader에서 redirect를 사용하는 것이 이 훅보다 나은 경우가 많지만 여전히 사용 사례가 있다.

 

 

Arguments

to: string

가장 기본적인 사용법은 href 문자열을 사용한다. 

경로는 상대적일 수 있다.

navigate("/some/path");

navigate("..");
navigate("../other/path");

 

 

to: Partial<Path>

Partial<Path> 값을 전달할 수 있다.

navigate({
  pathname: "/some/path",
  search: "?query=string",
  hash: "#hash",
});

 

 

to: Number

숫자를 전달하면 브라우저가 기록 스택에서 뒤로 또는 앞으로 이동하도록 지시한다.

navigate(-1); // 뒤로 가기
navigate(1); // 앞으로 가기
navigate(-2); // 전전으로 가기

브라우저의 기록 스택 범위가 애플리케이션에만 국한되지 않기 때문에 이로 인해 애플리케이션이 종료될 수 있다.

 

 

options

두 번째 인수는 옵션 객체이다.

navigate(".", {
  replace: true,
  relative: "path",
  state: { some: "state" },
});
  • replacement : boolean - 새 항목을 푸시하는 대신 기록 스택의 현재 항목을 바꿈
  • relative : "rout" | "path" - 링크의 상대 경로 동작을 정의
    • "route" - 라우트 계층 구조를 사용하므로 ".."는 현재 라우트 패턴의 모든 URL 세그먼트를 제거
    • "path" - URL 경로를 사용하므로 ".."는 하나의 URL 세그먼트를 제거
  • state : any - 다음 위치에 영구적인 클라이언트 측 라우팅 상태를 추가함
  • preventScrollReset : boolean - <ScrollRestoration>을 사용하는 경우, 탐색 시 스크롤 위치가 창 상단으로 재설정되는 것을 방지
  • unstable_flushSync : boolean - 기본값 React.startTransition 대신 ReactDOM.flushSync 호출에서 탐색에 대한 초기 상태 업데이트를 감쌈
  • unstable_viewTransition : boolean - document.startViewTransition( )에서 최종 상태 업데이트를 감싸 이 탐색에 대한 보기 전환을 활성화함
    • 이 뷰 전환에 특정 스타일을 적용해야하는 경우, unstable_useViewTransitionState( )도 활용해야 함

 

 

 


- useNavigation

보류 중인 페이지 탐색에 대한 정보를 제공한다.

import { useNavigation } from "@remix-run/react";

function SomeComponent() {
  const navigation = useNavigation();
  // ...
}

 

 

Properties

navigation.formAction

제출된 폼(이 있는 경우)의 action

// 다음 중 하나로 설정
<Form action="/some/where" />;
submit(formData, { action: "/some/where" });

 

 

navigation.formMethod

제출된 폼(이 있는 경우)의 메소드

// 다음 중 하나로 설정
<Form method="get" />;
submit(formData, { method: "get" });

 

 

navigation.formData

<Form> 또는 useSubmit에서 시작된 모든 DELETE, PATCH, POST, PUT 탐색에는 폼의 제출 데이터가 첨부된다.

이는 submit.formData의 FormData 객체를 사용해 "낙관적 UI"를 구축하는 데 주로 유용하다.

// email 필드를 가진 폼
<Form method="post" action="/signup">
  <input name="email" />
</Form>;

// 탐색이 보류되는 동안 네비게이션은 'navigation.formData'에 필드 값을 가짐
navigation.formData.get("email");

GET 폼 제출의 경우에는, formData는 비어있을 것이고 데이터는 navigation.location.search에 반영된다.

 

 

navigation.location

다음 위치가 무엇일지를 알려준다.

 

 

navigation.state

  • idle - 보류 중인 탐색 없음
  • submitting - POST, PUT, PATCH, DELETE를 사용한 폼 제출로 인해 라우팅 action이 호출되고 있음
  • loading - 다음 페이지를 렌더하기 위해 다음 라우트에 대한 loader가 호출됨

일반 탐색 및 GET 폼 제출은 다음 상태를 통해 전환된다.

idle → loading → idle

 

POST, PUT, PATCH, DELETE 전환이 포함된 폼 제출은 다음 상태를 통해 이루어진다.

idle → submitting → loading → idle

 

 

 

 

🤔 useNavigate와 useNavigation의 차이?

useNavigate useNavigation
현재 경로에서 다른 경로로 이동 현재 라우팅 정보에 접근
클릭 또는 다른 이벤트에 의해 이동할 때, 조건에 따라 동적으로 다른 경로로 이동할 때 사용 현재 경로에 따라 다른 내용을 렌더링할 때, 네비게이션 링크를 만들 때 사용

 

 

 

 


- useNavigationType

유저가 현재 위치에 도착했을 때 사용된 탐색 유형을 반환한다.

import { useNavigationType } from "@remix-run/react";

function SomeComponent() {
  const navigationType = useNavigationType();
  // ...
}

 

 

반환 값

  • PUSH : 유저가 기록 스택 푸시 작업(링크 클릭, 폼 제출 등)을 통해 현재 페이지로 왔음
  • REPLACE : 유저가 기록 스택의 교체 작업을 통해 현재 페이지로 왔음(뒤로 또는 앞으로 가기 버튼 클릭, navigate(-1) 또는 navigatie(1) 호출)

 

 

 


- useOutlet

라우트 계층 구조의 이 수준에서의 하위 경로에 대한 요소를 반환한다.

이 훅은 하위 경로를 렌더링하기 위해 <Outlet>에서 내부적으로 사용된다.

import { useOutlet } from "@remix-run/react";

 

 

 

 


- useOutletContext

가장 가까운 상위 <Outlet context={value} /> 컴포넌트에서 컨텍스트 값을 반환하는 React Context를 통한 Convenience API이다.

import { useOutletContext } from "@remix-run/react";

function Child() {
  const myValue = useOutletContext();
  // ...
}

 

 

 

 


-useParams

경로와 일치하는 현재 URL에서 동적 파라미터의 키-값 쌍 객체를 반환한다.

하위 경로는 상위 경로의 모든 매개변수를 상속한다.

import { useParams } from "@remix-run/react";

function SomeComponent() {
  const params = useParams();
  // ...
}

 

routes/posts/$postId와 같은 경로가 /posts/123과 일치한다고 가정하면 params.postId는 "123"이 된다.

splat routes에 대한 파라미터는 params["*"]로 사용 가능하다.

 

 

 


- unstable_usePrompt

현재 위치에서 벗어나기 전에 window.confirm을 통해 유저에게 확인 메세지를 표시할 수 있다.

 

이는 React Router 애플리케이션 내의 클라이언트 측 탐색에만 작동하며 문서 요청을 차단하지 않는다. 

문서 탐색을 방지하려면 자체 'beforeunload'이벤트 핸들러를 추가해야 한다.

 

function ImportantForm() {
  const [value, setValue] = React.useState("");

  // 데이터가 input에 입력되면 다른 곳으로 이동하는 것을 차단함
  unstable_usePrompt({
    message: "Are you sure?",
    when: ({ currentLocation, nextLocation }) =>
      value !== "" &&
      currentLocation.pathname !== nextLocation.pathname,
  });

  return (
    <Form method="post">
      <label>
        Enter some important data:
        <input
          name="data"
          value={value}
          onChange={(e) => setValue(e.target.value)}
        />
      </label>
      <button type="submit">Save</button>
    </Form>
  );
}

 

 

 

 


- useResolvedPath

현재 위치의 경로 이름에 대해 주어진 값의 pathname을 확인하고 Path 객체를 반환한다.

import { useResolvedPath } from "@remix-run/react";

function SomeComponent() {
  const path = useResolvedPath("../some/where");
  path.pathname;
  path.search;
  path.hash;
  // ...
}

이는 상대적인 값에서 링크를 구축할 때 유용하며 <NavLink>에 대해 내부적으로 사용된다.

 

 

 

 


- 🆕 useRevalidator

창 포커스 또는 간격 폴링과 같은 일반적인 데이터 변형 이외의 이유로 페이지의 데이터 유효성을 다시 검사한다.

import { useRevalidator } from "@remix-run/react";

function WindowFocusRevalidator() {
  const revalidator = useRevalidator();

  useFakeWindowFocus(() => {
    revalidator.revalidate();
  });

  return (
    <div hidden={revalidator.state === "idle"}>
      Revalidating...
    </div>
  );
}

Remix는 action이 호출될 때 이미 페이지의 데이터를 자동으로 다시 검증한다.

유저 상호 작용에 대한 응답으로 데이터에 대한 일반적인 CRUD 작업에 이 기능을 사용하는 경우, 이 작업을 자동으로 수행하는 <Form>, useSubmit 또는 useFetcher와 같은 다른 API를 활용하지 않을 가능성이 높다.

 

 

Properties

revalidator.state

재검증 상태. "idle" 또는 "loading" 중에 하나

 

 

revalidator.revalidate()

재검증을 시작한다.

function useLivePageData() {
  const revalidator = useRevalidator();
  const interval = useInterval(5000);

  useEffect(() => {
    if (revalidator.state === "idle") {
      revalidator.revalidate();
    }
  }, [interval, revalidator]);
}

 

 

✏️ NOTE

더보기

useRevalidator의 여러 항목을 동시에 렌더링할 수 있지만, 그 아래에는 싱글톤이 있다. 이는 하나의 revalidator.revalidate()가 호출되면 모든 인스턴스가 함께 "loading" 상태로 전환됨을 의미한다(또는 오히려 모두 싱글톤 상태를 보고하도록 업데이트된다).

다른 이유로 재검증이 이미 진행 중인 경우 revalidate( )를 호출하면 경쟁 조건이 자동으로 처리된다.  

재검증이 진행되는 동안 탐색이 발생하면 재검증이 취소되고 다음 페이지를 위해 모든 로더에서 새로운 데이터가 요청된다.

 

 

 

 


- 🆕 useRouteError

ErrorBoundary에서 사용할 action, loader 또는 렌더링 중에 발생한 오류에 액세스한다.

// routes/some-route.tsx
export function ErrorBoundary() {
  const error = useRouteError();
  return <div>{error.message}</div>;
}

 

 

 

 


- useRouteLoaderData

특정 경로에 대한 loader 데이터를 ID별로 반환한다.

import { useRouteLoaderData } from "@remix-run/react";

function SomeComponent() {
  const { user } = useRouteLoaderData("root");
}

 

Remix는 경로 ID를 자동으로 생성한다.

확장자가 없는 앱 폴더를 기준으로 한 라우트 파일의 경로일 뿐이다.

Route Filename Route ID
app/root.tsx "root"
app/routes/teams.tsx "routes/teams"
app/routes/teams.$id.tsx "routes/teams.$id"

 

 

 

 


- useSearchParams

현재 URL의 searchParams의 튜플과 이를 업데이트하는 함수를 반환한다.

검색 파라미터를 설정하면 탐색이 발생한다.

import { useSearchParams } from "@remix-run/react";

export function SomeComponent() {
  const [searchParams, setSearchParams] = useSearchParams();
  // ...
}

 

 

Signature

const [searchParams, setSearchParams] = useSearchParams();

 

searchParams

반환된 첫 번째 값은 웹 URLSearchParams 객체이다.

 

 

setSearchParams(params, navigateOptions)

반환된 두 번째 값을 새로운 검색 매개변수를 설정하는 함수이며 호출 시 탐색을 유발한다.

탐색 옵션과 함께 선택적인 두 번째 인수를 전달하여 탐색을 구성할 수 있다.

<button
  onClick={() => {
    const params = new URLSearchParams();
    params.set("someKey", "someValue");
    setSearchParams(params, {
      preventScrollReset: true,
    });
  }}
/>

 

 

setSearchParams((prevParams) => newParams, navigateOptions)

setter 함수는 새로운 검색 매개변수를 설정하는 함수도 지원한다.

<button
  onClick={() => {
    setSearchParams((prev) => {
      prev.set("someKey", "someValue");
      return prev;
    });
  }}
/>

 

 

 

 


- useSubmit

<Form> 명령어 버전을 사용하면 개발자가 유저 대신 폼을 제출할 수 있다.

import { useSubmit } from "@remix-run/react";

function SomeComponent() {
  const submit = useSubmit();
  return (
    <Form
      onChange={(event) => {
        submit(event.currentTarget);
      }}
    />
  );
}

 

 

Signature

submit(targetOrData, options);

 

▪︎ targetOrData

다음 중 하나일 수 있음

 

HTMLFormElement 인스턴스

<Form
  onSubmit={(event) => {
    submit(event.currentTarget);
  }}
/>

 

 

FormData 인스턴스

const formData = new FormData();
formData.append("myKey", "myValue");
submit(formData, { method: "post" });

 

 

FormData으로 직렬화 될 일반 객체

submit({ myKey: "myValue" }, { method: "post" });

 

 

JSON으로 직렬화 될 일반 객체

submit(
  { myKey: "myValue" },
  { method: "post", encType: "application/json" }
);

 

 

 

▪︎ options

제출을 위한 옵션들은 <Form> props와 동일하다. 모든 옵션은 선택 사항이다.

submit(data, {
  action: "",
  method: "post",
  encType: "application/x-www-form-urlencoded",
  preventScrollReset: false,
  replace: false,
  relative: "route",
});
  • action : 제출할 href. 기본값은 현재 라우트 경로
  • method : POST처럼 사용하는 HTTP 메소드. 기본값은 GET
  • encType : 폼 제출에 사용할 인코딩 유형.
    • 기본값은 application/x-www-form-urlencoded
    • multipart/form-data
    • application/json
    • text/plain
  • navigation : false로 지정하면 탐색을 수행하는 대신 fetcher를 사용해 제출
  • fetcherKey : navigation:false를 통해 fetcher를 사용해 제출할 때 사용할 fetcher key
  • preventScrollReset : 데이터가 제출될 때 스크롤 위치가 창 상단으로 재설정되는 것을 방지. 기본값은 false
  • replace : 새 항목을 푸시하는 대신 기록 스택의 현재 항목을 바꿈. 기본값은 false
  • relative : 상대 경로 확인 동작을 정의. 
    • route - 경로 계층 구조 기준
    • path - URL 기준
  • unstable_flushSync : 기본 React.startTransition 대신 ReactDOM.flushSync 호출에서 이 탐색에 대한 초기 상태 업데이트를 랩핑
  • unstable_viewTransition : document.startViewTransition( )에서 최종 상태 업데이트를 랩핑하여 이 탐색에 대한 보기 전환을 활성화
    • 이 뷰 전환에 특정 스타일을 적용해야 하는 경우 unstable_useViewTransitionState( )도 활용해야함

 

 

 


- usestable_useViewTransitionState

지정된 위치에 대한 활성화된 View Transition이 있는 경우 true를 반환한다.

이는 View Transition을 추가로 커스터마이즈하기 위해 요소에 더 세분화된 스타일을 적용하는 데 사용할 수 있다.

이를 위해서는 Link(또는 Form, NavLink, navigate, submit call)의 props에 unstable_viewTransition을 통해 지정된 탐색에 대한 View Transition이 활성화되어 있어야 한다.


대상 페이지의 히어로 이미지로 확장해야 하는 목록의 이미지를 클릭하는 것을 고려하세요!

function NavImage({ src, alt, id }) {
  const to = `/images/${idx}`;
  const vt = unstable_useViewTransitionState(href);
  return (
    <Link to={to} unstable_viewTransition>
      <img
        src={src}
        alt={alt}
        style={{
          viewTransitionName: vt ? "image-expand" : "",
        }}
      />
    </Link>
  );
}
728x90