React Router v6.4+ 数据 API:重试加载程序而不显示错误

问题描述 投票:0回答:1

使用react-router 6.21.1和新的数据api,我的路由设置如下:

const routes = [
    {
        element: <RootWrapper/>,
        errorElement: <ErrorWrapper/>,
        children: [
            {path: "/login?", element: <LoginWrapper/>},
            {path: "/logout", element: <Logout/>},
            {
                id: "AuthenticatedRoot",
                element: <AuthenticatedRoot/>,
                children: [
                    // ...
                    {path: "/dashboard", element: <Dashboard/>, loader: fetchDashboard},
                ]
            }
        ]
]

我的仪表板视图 24/7 全天候显示,并且每 5 分钟重新验证一次。它需要在出现最多 5 个错误后保持运行状态,以便为发布或其他未知的停机提供至少 30 分钟的时间。手动使用 useEffects 来获取数据时很简单,因为我可以处理从获取请求返回的错误:

await axios.get('dashboard')
    .then(
        response => {setData(response.data)},
        error => {
            setRetries(origRetries => {
                if (origRetries >= 6) {
                    setError(true)
                    setErrorMessage(error.message)
                    return 0
                } else {
                    return origRetries + 1
                }
            })
        }
    )

有没有办法用新的装载机做这样的事情?

javascript reactjs react-router react-router-dom
1个回答
0
投票

您可以编写

fetchDashboard
加载器函数来关闭重试“状态”。实现可能类似于以下内容:

const fetchDashboard = () => {
  let cache = {};
  let retry = 0;

  return async () => {
    try {
      const result = await axios.get('dashboard');

      // Success, cache result and reset retry state
      cache = result;
      retry = 0;

      return result;
    } catch (error) {
      // Failure/error, increment retry count
      retry++;

      if (retry > 5) {
        // Rethrow error if ran out of retries
        throw error;
      } else {
        // Otherwise return cached result
        return cache;
      }
    }
  };
};
const routes = [
  {
    element: <RootWrapper />,
    errorElement: <ErrorWrapper />,
    children: [
      { path: "/login?", element: <LoginWrapper /> },
      { path: "/logout", element: <Logout /> },
      {
        id: "AuthenticatedRoot",
        element: <AuthenticatedRoot />,
        children: [
          // ...
          { 
            id: "dashboard",
            path: "/dashboard",
            element: <Dashboard />,
            errorElement: <Dashboard />, // <-- render as error element too!
            loader: fetchDashboard(),    // <-- invoke outer function
          },
        ]
      }
    ],
  },
];
import {
  useRouteError,
  useRouteLoaderData,
  useNavigate,
  useNavigation
} from "react-router-dom";

const Dashboard = () => {
  const navigate = useNavigate();
  const { state } = useNavigation(); // "idle"/"loading", could be handy

  const data = useRouteLoaderData("dashboard");
  const error = useRouteError();

  useEffect(() => {
    const timer = setInterval(() => {
      navigate("/dashboard", { replace: true });
    }, 1000 * 60 * 5); // 5 minute interval
    return () => clearInterval(timer);
  }, []);

  useEffect(() => {
    console.log("Dashboard", { data, error });
  }, [data, error]);

  return (
    ...
  );
};

演示

Edit react-router-v6-4-data-api-retry-loader-without-displaying-error

© www.soinside.com 2019 - 2024. All rights reserved.