You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:05:21