使用Remix.js <Form>组件提交后无法清空输入框的问题咨询
在Remix.js中解决
针对嵌套路由下提交表单后输入框保留值的情况,有几种更优雅的解决方式,替代手动清空的临时方案:
方法1:通过useNavigation状态重置受控表单
如果你的表单是受控组件(输入值绑定到state),可以利用useNavigation监听提交状态,完成后重置state:
import { Form, useNavigation } from "@remix-run/react"; import { useState, useEffect } from "react"; export default function ChildRouteForm() { const [formState, setFormState] = useState({ title: "", body: "" }); const navigation = useNavigation(); // 监听导航状态,提交完成后重置表单 useEffect(() => { if (navigation.state === "idle" && navigation.formMethod === "post") { setFormState({ title: "", body: "" }); } }, [navigation]); return ( <Form action="/route/add" method="post"> <input type="text" name="title" value={formState.title} onChange={(e) => setFormState({ ...formState, title: e.target.value })} /> <textarea name="body" value={formState.body} onChange={(e) => setFormState({ ...formState, body: e.target.value })} /> <button type="submit">提交</button> </Form> ); }
方法2:通过重定向参数触发子路由重置
在action的重定向中添加一个随机参数,子路由监听该参数变化来重置表单:
父路由action修改:
export const action: ActionFunction = async ({ request }) => { const formData = await request.formData(); const data = Object.fromEntries(formData); await doSomething(data); // 添加随机参数触发子路由更新 return redirect(`/route/add?refresh=${Date.now()}`); };
子路由组件:
import { Form, useSearchParams } from "@remix-run/react"; import { useEffect, useRef } from "react"; export default function ChildRouteForm() { const formRef = useRef(null); const [searchParams] = useSearchParams(); useEffect(() => { // 当refresh参数变化时,重置表单 if (searchParams.get("refresh")) { formRef.current?.reset(); } }, [searchParams]); return ( <Form ref={formRef} action="/route/add" method="post"> <input type="text" name="title" /> <textarea name="body" /> <button type="submit">提交</button> </Form> ); }
方法3:使用Remix的useReset钩子
Remix提供了useReset钩子,可以直接获取表单重置函数,在提交完成后调用:
import { Form, useNavigation, useReset } from "@remix-run/react"; import { useEffect } from "react"; export default function ChildRouteForm() { const reset = useReset(); const navigation = useNavigation(); useEffect(() => { // 提交完成后执行重置 if (navigation.state === "idle" && navigation.formMethod === "post") { reset(); } }, [navigation, reset]); return ( <Form action="/route/add" method="post"> <input type="text" name="title" /> <textarea name="body" /> <button type="submit">提交</button> </Form> ); }
方法4:给Outlet添加动态key强制子路由重挂载
在父路由的Outlet组件上添加一个随提交状态变化的key,迫使子路由重新渲染:
父路由组件:
import { Outlet, useNavigation } from "@remix-run/react"; export default function ParentRoute() { const navigation = useNavigation(); // 用导航状态或随机值作为key const outletKey = navigation.state === "loading" ? Date.now() : navigation.formKey; return ( <div> <h1>父路由内容</h1> <Outlet key={outletKey} /> </div> ); }
这样每次表单提交后,Outlet的key变化,子路由会重新挂载,输入框自然清空。
内容的提问来源于stack exchange,提问作者Pavel L
相关产品推荐
相关产品推荐

