useSubmit
The imperative version of <Form>
that lets you, the programmer, submit a form instead of the user.
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]); }
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
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" />;
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.