useSubmit

useSubmit

The imperative version of <Form> that lets you, the programmer, submit a form instead of the user.

This feature only works if using a data router, see Picking a Router

For example, submitting the form every time a value changes inside the 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>  ); } 

This can also be useful if you'd like to automatically sign someone out of your website after a period of inactivity. In this case, we've defined inactivity as the user hasn't navigated to any other pages after 5 minutes.

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

Submit target

The first argument to submit accepts many different values.

You can submit any form or form input element:

// input element events <input onChange={(event) => submit(event.currentTarget)} />;  // React refs let ref = useRef(); <button ref={ref} />; submit(ref.current); 

You can submit FormData:

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

Or you can submit URLSearchParams:

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

Or anything that the URLSearchParams constructor accepts:

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

The default behavior if you submit a JSON object for a POST submission is to encode the data into 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 

Or you can opt-into JSON encoding:

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 

Or plain text:

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 options

The second argument is a set of options that map (mostly) directly to form submission attributes:

submit(null, {  method: "post",  action: "/logout", });  // same as <Form action="/logout" method="post" />; 

Please see the Splat Paths section on the useResolvedPath docs for a note on the behavior of the future.v7_relativeSplatPath future flag for relative useSubmit() action behavior within splat routes

Because submissions are navigations, the options may also contain the other navigation related props from <Form> such as:

  • fetcherKey
  • navigate
  • preventScrollReset
  • relative
  • replace
  • state
  • viewTransition

options.flushSync

The flushSync option tells React Router DOM to wrap the initial state update for this submission 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.

Docs and examples CC 4.0
Edit