简体   繁体   English

反应重定向挂钩无限循环

[英]React Redirect Hook Infinte Loop

I don't know the reason but if I try use the Navigate Hook to redirect to a specific path when my desktop changes mode, it dives into a sort of "infinite loop " in the browser:我不知道原因,但如果我在桌面更改模式时尝试使用 Navigate Hook 重定向到特定路径,它会在浏览器中陷入一种“无限循环”:

history.ts:633 Throttling navigation to prevent the browser from hanging. history.ts:633 限制导航以防止浏览器挂起。 See https://crbug.com/1038223 .请参阅https://crbug.com/1038223 Command line switch --disable-ipc-flooding-protection can be used to bypass the protection命令行开关 --disable-ipc-flooding-protection 可以用来绕过保护

react-dom.development.js:86 Warning: Maximum update depth exceeded. react-dom.development.js:86 警告:超出最大更新深度。 This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.当组件在 useEffect 中调用 setState 时可能会发生这种情况,但 useEffect 要么没有依赖项数组,要么依赖项之一在每次渲染时都会发生变化。

在此处输入图像描述

My App.js我的 App.js

import "./App.scss";
import React, { Fragment, useEffect } from "react";
import { useMediaQuery } from "./hooks/MediaQuery"; 
import Desktop from "./Pages/Desktop/Desktop";
import { Route, Routes, Navigate } from "react-router-dom";

function App() {
  return (
    <Fragment>
      <div className="App">
        <Routes>
          <Route
            exact
            path="*"
            element={
              useMediaQuery(750) ? (
                <Desktop replace to="/" />
              ) : (
                <Navigate replace to="/m" />
              )
            }
          />
        </Routes>
      </div>
    </Fragment>
  );
}

export default App;

It seems the issue is an unconditional redirect loop is created in mobile views, from "*" to "/m" which is matched by "*" and the Navigate component is rendered again.问题似乎是在移动视图中创建了一个无条件重定向循环,从"*""/m" ,与"*"匹配,然后再次呈现Navigate组件。

To stop this you might consider moving the redirect into a component lifecycle and only redirect if not already on "/m" .要停止这种情况,您可以考虑将重定向移动到组件生命周期中,并且仅在不在"/m"上时才重定向。 Here's a basic implementation using a useEffect hook in the media query hook.这是在媒体查询挂钩中使用useEffect挂钩的基本实现。

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

const useMediaQueryRedirect = (width) => {
  const navigate = useNavigate();
  const isMobileMatch = useMatch("/m");

  useEffect(() => {
    const checkWidth = () => {
      if (window.innerWidth < width && !isMobileMatch) {
        navigate("/m");
      }
      if (window.innerWidth >= width && isMobileMatch) {
        navigate("/");
      }
    };
    window.addEventListener("resize", checkWidth, { passive: true });
    return () => {
      window.removeEventListener("resize", checkWidth, { passive: true });
    };
  }, [isMobileMatch, navigate, width]);
};

Create a layout route to use the hook and render the appropriate nested routes.创建布局路由以使用挂钩并呈现适当的嵌套路由。

import { Route, Routes, Outlet } from "react-router-dom";

const MediaLayout = () => {
  useMediaQueryRedirect(750);

  return <Outlet />;
};

...

return (
  ...
  <Routes>
    <Route element={<MediaLayout />}>
      <Route path="/*" element={/* Main component routes */} />
      <Route path="/m/*" element={/* Mobile component routes */} />
    </Route>
  </Routes>
  ...
);

编辑 react-redirect-hook-infinte-loop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM