useFetcher
On this page

useFetcher

一个用于在导航之外与服务器交互的钩子。

¥A hook for interacting with the server outside of navigation.

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

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

选项

¥Options

key

默认情况下,useFetcher 会生成一个作用域为该组件的唯一抓取器(但是,在运行过程中,它可能会在 useFetchers() 中被查找)。如果你想使用自己的密钥标识某个获取器,以便可以从应用的其他位置访问它,可以使用 key 选项:

¥By default, useFetcher generates a unique fetcher scoped to that component (however, it may be looked up in useFetchers() while in-flight). If you want to identify a fetcher with your own key such that you can access it from elsewhere in your app, you can do that with the key option:

function AddToBagButton() {
  const fetcher = useFetcher({ key: "add-to-bag" });
  return <fetcher.Form method="post">...</fetcher.Form>;
}

// Then, up in the header...
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

只要知道,当 URL 与父路由的路径匹配时,索引将在 <Form> 内部渲染即可。

¥Just like <Form> except it doesn't cause a navigation.

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

方法

¥Methods

fetcher.submit(formData, options)

将表单数据提交到路由。虽然多个嵌套路由可以匹配一个 URL,但只会调用叶路由。

¥Submits form data to a route. While multiple nested routes can match a URL, only the leaf route will be called.

formData 可以是多种类型:

¥The formData can be multiple types:

  • FormData - 一个 FormData 实例。

    ¥FormData - A FormData instance.

  • HTMLFormElement - 一个 <form> DOM 元素。

    ¥HTMLFormElement - A <form> DOM element.

  • Object - 一个键/值对对象,默认情况下将转换为 FormData 实例。你可以传递更复杂的对象,并通过指定 encType: "application/json" 将其序列化为 JSON。详细信息请参见 useSubmit

    ¥Object - An object of key/value pairs that will be converted to a FormData instance by default. You can pass a more complex object and serialize it as JSON by specifying encType: "application/json". See useSubmit for more details.

如果方法是 GET,则调用路由 loader,并将 formData 序列化为 URLSearchParams 的 URL。如果是 DELETEPATCHPOSTPUT,则路由 action 将被调用,且 formData 为路由主体。

¥If the method is GET, then the route loader is being called and with the formData serialized to the url as URLSearchParams. If DELETE, PATCH, POST, or PUT, then the route action is being called with formData as the body.

// Submit a FormData instance (GET request)
const formData = new FormData();
fetcher.submit(formData);

// Submit the HTML form element
fetcher.submit(event.currentTarget.form, {
  method: "POST",
});

// Submit key/value JSON as a FormData instance
fetcher.submit(
  { serialized: "values" },
  { method: "POST" }
);

// Submit raw JSON
fetcher.submit(
  {
    deeply: {
      nested: {
        json: "values",
      },
    },
  },
  {
    method: "POST",
    encType: "application/json",
  }
);

fetcher.submit 是对 fetcher 实例的 useSubmit 调用的封装器,因此它也接受与 useSubmit 相同的选项。

¥fetcher.submit is a wrapper around a useSubmit call for the fetcher instance, so it also accepts the same options as useSubmit.

fetcher.load(href, options)

从路由加载器加载数据。虽然多个嵌套路由可以匹配一个 URL,但只会调用叶路由。

¥Loads data from a route loader. While multiple nested routes can match a URL, only the leaf route will be called.

请注意,在索引路由的加载器上调用 load 时,必须包含 ?index 查询参数 以区分 index.tsx 布局和 root.tsx 路由。

¥Note that when calling load on an index route's loader, you must include an ?index query param to disambiguate between the index.tsx layout and the root.tsx route.

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

fetcher.load 仅在提交操作并通过 useRevalidator 发出显式重新验证请求后默认重新验证。由于 fetcher.load 会加载特定的 URL,因此它们不会在路由参数或 URL 搜索参数发生变化时重新验证。你可以使用 shouldRevalidate 来优化需要重新加载的数据。

¥fetcher.load's revalidate by default after action submissions and explicit revalidation requests via useRevalidator. Because fetcher.load loads a specific URL they don't revalidate on changes to route param or URL search param. You can use shouldRevalidate to optimize which data should be reloaded.

options.flushSync

flushSync 选项告诉 React Router DOM 将此 fetcher.load 的初始状态更新封装在 ReactDOM.flushSync 调用中,而不是默认的 React.startTransition。这允许你在更新刷新到 DOM 后立即执行同步 DOM 操作。

¥The flushSync option tells React Router DOM to wrap the initial state update for this fetcher.load in a ReactDOM.flushSync call instead of the default React.startTransition. This allows you to perform synchronous DOM actions immediately after the update is flushed to the DOM.

ReactDOM.flushSync 会降低 React 的优化程度,并可能影响应用的性能。

属性

¥Properties

fetcher.state

你可以使用 fetcher.state 了解获取器的状态。它将是以下之一:

¥You can know the state of the fetcher with fetcher.state. It will be one of:

  • idle — 未获取任何内容。

    ¥idle — Nothing is being fetched.

  • 提交中 — 表单已提交。如果方法是 GET,则调用的是路由 loader。如果是 DELETEPATCHPOSTPUT,则路由 action 将被调用。

    ¥submitting — A form has been submitted. If the method is GET, then the route loader is being called. If DELETE, PATCH, POST, or PUT, then the route action is being called.

  • loading — 提交 action 后,路由的加载器将被重新加载。

    ¥loading — The loaders for the routes are being reloaded after an action submission.

fetcher.data

actionloader 返回的响应数据存储在此处。数据设置完成后,即使重新加载和重新提交(例如在读取数据后再次调用 fetcher.load()),它仍会保留在抓取器中。

¥The returned response data from your action or loader is stored here. Once the data is set, it persists on the fetcher even through reloads and resubmissions (like calling fetcher.load() again after having already read the data).

fetcher.formData

提交到服务器的 FormData 实例存储在此处。这对于乐观 UI 很有用。

¥The FormData instance that was submitted to the server is stored here. This is useful for optimistic UIs.

fetcher.formAction

提交的 URL。

¥The URL of the submission.

fetcher.formMethod

提交的表单方法。

¥The form method of the submission.

其他资源

¥Additional Resources

讨论

¥Discussions

视频

¥Videos

Remix v2.17 中文网 - 粤ICP备13048890号