使用useNavigate未跳转页面反而添加div?求解决方案
React Router 跳转后组件附加在主页面的解决方法
我是React建站新手,尝试通过react-router提供的useNavigate()函数实现页面跳转,点击主页面按钮想跳转到独立组件About.tsx,但点击后About.tsx的div内容却附加在主页面侧边,而非跳转到仅包含该div的全新空白页面。已尝试重写函数、调整About页面,参考教程和工具均未解决,附上相关代码如下:
原代码
About.tsx
export const About = () => { return <div>About</div>; };
Main Page (App.tsx)
import { useNavigate, Route, Routes } from "react-router"; import { About } from "./About"; type ButtonProps = { text: string, onClicked: Function, }; function Button({ text, onClicked }: ButtonProps) { return ( <button className="px-5 border-sky-700 border-2 text-sky-600 rounded-full transform hover:bg-gray-800 hover:scale-125 transition duration-200" onClick={() => onClicked()} > {text} </button> ); } function Nav() { let navigate = useNavigate(); function navPath(path: string) { navigate(path); } return ( <div className="shadow-xl bg-sky-800 bg-opacity-10 md:w-3/2 lg:w-[60rem] top-10 h-16 flex items-center absolute justify-center space-x-12 z-10 rounded-full overflow-hidden"> <div className="w-50 items-center flex"> <Button text="Who Am I" onClicked={() => navigate("./About")} /> </div> </div> ); } function App() { return ( <main> //a few divs <Routes> <Route path="/About" element={<About />} /> </Routes> </main> ); } export default App;
Index.tsx
import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./pages/App"; import reportWebVitals from "./reportWebVitals"; import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); root.render( <BrowserRouter> <App /> </BrowserRouter> ); reportWebVitals();
问题原因
你的App组件中,主页面内容(//a few divs)和<Routes>是同级关系,这意味着无论当前路由匹配哪个组件,主页面内容都会始终渲染在页面上。点击跳转后,About组件只是在<Routes>区域内渲染,所以看起来像是附加在主页面侧边。
解决方法
步骤1:将主页面内容封装为独立路由组件
创建Home.tsx,把原来App中的主页面内容(包括Nav组件)移到这个组件里:
import { useNavigate } from "react-router"; type ButtonProps = { text: string, onClicked: () => void, }; function Button({ text, onClicked }: ButtonProps) { return ( <button className="px-5 border-sky-700 border-2 text-sky-600 rounded-full transform hover:bg-gray-800 hover:scale-125 transition duration-200" onClick={() => onClicked()} > {text} </button> ); } function Nav() { let navigate = useNavigate(); return ( <div className="shadow-xl bg-sky-800 bg-opacity-10 md:w-3/2 lg:w-[60rem] top-10 h-16 flex items-center absolute justify-center space-x-12 z-10 rounded-full overflow-hidden"> <div className="w-50 items-center flex"> <Button text="Who Am I" onClicked={() => navigate("/About")} /> {/* 改用绝对路径 */} </div> </div> ); } export const Home = () => { return ( <main> {/* 原来的主页面div内容 */} <Nav /> </main> ); };
步骤2:修改App组件的路由配置
让App组件只负责路由匹配,根路径渲染Home组件,/About路径渲染About组件:
import { Route, Routes } from "react-router"; import { About } from "./About"; import { Home } from "./Home"; function App() { return ( <Routes> <Route path="/" element={<Home />} /> <Route path="/About" element={<About />} /> </Routes> ); } export default App;
关键细节说明
- 路由结构调整:通过将主页面内容转为Home路由组件,确保
<Routes>只渲染当前匹配的路由组件,切换路由时会完全替换页面内容,实现全新页面的效果。 - 绝对路径跳转:把
navigate("./About")改成navigate("/About"),避免相对路径导致的路由匹配异常。
替代方案
如果不想拆分组件,也可以通过条件渲染控制主页面内容的显示:
import { useNavigate, Route, Routes, useLocation } from "react-router"; import { About } from "./About"; // ... Button和Nav组件代码不变 ... function App() { const location = useLocation(); // 只有当前路径是根路径时,才显示主页面内容 const showHomeContent = location.pathname === "/"; return ( <main> {showHomeContent && ( <> {/* 原来的主页面div内容 */} <Nav /> </> )} <Routes> <Route path="/About" element={<About />} /> </Routes> </main> ); } export default App;
这种方式通过useLocation获取当前路由路径,条件渲染主页面内容,也能实现跳转后只显示About组件的效果,但拆分组件的方式更符合React Router的最佳实践,代码结构更清晰。
内容的提问来源于stack exchange,提问作者sahil puth
相关产品推荐
相关产品推荐

