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

React Router:在fetcher.submit完成后从发起组件触发alert

问题需求

我需要在路由action返回的Promise完成后显示alert,但要从发起该action的组件中执行此操作。现有代码如下:

App.jsx 代码

import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { TestFetcher } from "./test";

export default function App() {
  const router = createBrowserRouter([
    {
      path: "/",
      element: <TestFetcher />,
      action: async () => {
        await new Promise((resolve, reject) => setTimeout(resolve, 3000));
        return null;
      }
    }
  ]);

  return <RouterProvider router={router} />;
}

TestFetcher 组件代码

import { useFetcher } from "react-router-dom";

export function TestFetcher() {
  const fetcher = useFetcher();

  return (
    <>
      <button onClick={click}>{fetcher.state}</button>
    </>
  );

  function click() {
    fetcher.submit({ test: "test" }, { method: "post", action: "/" });
    // 需要在此处触发alert
  }
}
解决方案

可以通过监听fetcher.state的变化实现需求。调用fetcher.submit后,fetcher.state会变为"loading",当路由action中的Promise完成后,状态会切换回"idle"。利用useEffect监听这个状态变化,就能在action完成后触发alert:

修改后的TestFetcher组件代码:

import { useFetcher, useEffect } from "react-router-dom";

export function TestFetcher() {
  const fetcher = useFetcher();

  useEffect(() => {
    // 当状态从loading变为idle时,说明action已完成
    if (fetcher.state === "idle" && fetcher.formData) {
      alert("Action执行完成!");
      // 清空formData避免重复触发
      fetcher.formData = null;
    }
  }, [fetcher.state, fetcher.formData]);

  return (
    <>
      <button onClick={click}>{fetcher.state}</button>
    </>
  );

  function click() {
    fetcher.submit({ test: "test" }, { method: "post", action: "/" });
  }
}

说明

  • fetcher.state:提交后进入loading状态,action完成后回到idle
  • 加入fetcher.formData的判断是为了避免组件初始化时(状态也是idle)误触发alert,提交后formData会有值,执行alert后手动清空,确保每次提交只触发一次

内容的提问来源于stack exchange,提问作者user19315471

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:40:41