主分支
分支
main (6.23.1)dev
版本
6.23.1v4/5.xv3.x
useSubmit

useSubmit

<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>
  );
}

这在您希望在用户一段时间不活动后自动将其从网站注销时也很有用。在这种情况下,我们定义不活动为用户在 5 分钟后没有导航到任何其他页面。

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]);
}

提交目标

提交的第一个参数接受许多不同的值。

您可以提交任何表单或表单输入元素

// input element events
<input onChange={(event) => submit(event.currentTarget)} />;

// React refs
let ref = useRef();
<button ref={ref} />;
submit(ref.current);

您可以提交 FormData

let formData = new FormData();
formData.append("cheese", "gouda");
submit(formData);

或者您可以提交 URLSearchParams

let searchParams = new URLSearchParams();
searchParams.append("cheese", "gouda");
submit(searchParams);

或者任何 URLSearchParams 构造函数接受的内容

submit("cheese=gouda&toasted=yes");
submit([
  ["cheese", "gouda"],
  ["toasted", "yes"],
]);

如果您为 POST 提交提交 JSON 对象,则默认行为是将数据编码为 FormData

submit(
  { key: "value" },
  {
    method: "post",
    encType: "application/x-www-form-urlencoded",
  }
);
// will serialize into request.formData() in your action
// and will show up on useNavigation().formData during the navigation

或者您可以选择 JSON 编码

submit(
  { key: "value" },
  { method: "post", encType: "application/json" }
);
// will serialize into request.json() in your action
// and will show up on useNavigation().json during the navigation

submit('{"key":"value"}', {
  method: "post",
  encType: "application/json",
});
// will encode into request.json() in your action
// and will show up on useNavigation().json during the navigation

或纯文本

submit("value", { method: "post", encType: "text/plain" });
// will serialize into request.text() in your action
// and will show up on useNavigation().text during the navigation

提交选项

第二个参数是一组选项,这些选项(大部分)直接映射到表单提交属性

submit(null, {
  method: "post",
  action: "/logout",
});

// same as
<Form action="/logout" method="post" />;

请参阅 Splat 路径 部分,了解 useResolvedPath 文档中有关 future.v7_relativeSplatPath 未来标志在 splat 路由中相对 useSubmit() action 行为的行为说明

由于提交是导航,因此选项可能还包含来自 <Form> 的其他与导航相关的道具,例如

  • fetcherKey
  • navigate
  • preventScrollReset
  • relative
  • replace
  • state
  • unstable_viewTransition

options.unstable_flushSync

unstable_flushSync 选项告诉 React Router DOM 将此提交的初始状态更新包装在一个 ReactDOM.flushSync 调用中,而不是默认的 React.startTransition。这使您能够在更新刷新到 DOM 后立即执行同步 DOM 操作。

请注意,此 API 被标记为不稳定,并且可能会在没有重大版本的情况下发生重大更改