React Router中如何在/cabinet路由下隐藏Footer组件
问题根因
你无法在App组件内调用react-router提供的路由钩子,是因为<BrowserRouter>被写在了App组件的内部,所有需要使用路由相关能力的组件都必须是<BrowserRouter>的子组件,App本身不在Router的上下文范围内,所以钩子调用会失效。而直接用window.location.pathname无法响应路由变化,是因为这个值不属于React的状态,变更时不会触发组件重渲染。
解决方案
方案1:调整结构 + useLocation钩子(更推荐)
- 把
<BrowserRouter>移到App组件的外层,通常在入口文件index.js中调整即可:
// index.js 示例 import { BrowserRouter } from 'react-router-dom' import { App } from './App' import ReactDOM from 'react-dom' ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') )
- 修改
App组件代码,删除内部的<BrowserRouter>,用useLocation获取实时路由路径做判断:
import { Redirect, Route, Switch, useLocation } from "react-router-dom"; import "./styles.css"; import { Home } from "./pages/Home"; import { Catalog } from "./pages/Catalog"; import { Cabinet } from "./pages/Cabinet"; import { Header } from "./components/Header"; import { Footer } from "./components/Footer"; import { Page404 } from "./pages/Page404"; const App = () => { const location = useLocation(); // 路径不是/cabinet时就显示Footer const showFooter = location.pathname !== '/cabinet' return ( <> <Header /> <Switch> <Route path={"/"} exact> <Home /> </Route> <Route path={"/catalog"} exact> <Catalog /> </Route> <Route path={"/cabinet"} exact> <Cabinet /> </Route> <Route path={"*"}> <Page404 /> </Route> </Switch> {showFooter && <Footer />} </> ); }; export { App };
方案2:不调整外层结构,直接用Route组件做匹配
如果不想修改外层代码,也可以直接利用Route的路径匹配能力控制Footer的渲染,不用额外调用钩子:
import { Redirect, Route, Switch } from "react-router-dom"; import { BrowserRouter } from "react-router-dom"; import "./styles.css"; import { Home } from "./pages/Home"; import { Catalog } from "./pages/Catalog"; import { Cabinet } from "./pages/Cabinet"; import { Header } from "./components/Header"; import { Footer } from "./components/Footer"; import { Page404 } from "./pages/Page404"; const App = () => { return ( <> <BrowserRouter> <Header /> <Switch> <Route path={"/"} exact> <Home /> </Route> <Route path={"/catalog"} exact> <Catalog /> </Route> <Route path={"/cabinet"} exact> <Cabinet /> </Route> <Route path={"*"}> <Page404 /> </Route> </Switch> {/* 仅匹配到非/cabinet的路径时渲染Footer */} <Route path={["/", "/catalog", "*"]} exact> <Footer /> </Route> </BrowserRouter> </> ); }; export { App };
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

