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:
history.ts:633 Throttling navigation to prevent the browser from hanging. See
My 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;
CodePudding user response:
It seems the issue is an unconditional redirect loop is created in mobile views, from
"*"
to"/m"
which is matched by"*"
and theNavigate
component is rendered again.To stop this you might consider moving the redirect into a component lifecycle and only redirect if not already on
"/m"
. Here's a basic implementation using auseEffect
hook in the media query hook.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> ... );