反应路由:检测路由更改

时间:2020-02-27 20:24:23

标签: reactjs react-router react-router-dom

我在使用React Router v5检测路由更改时遇到问题。 愿望是,当路由更改时我想输出一个console.log。愿望是,当路由更改时我想要在App组件的console.log中输出该路由(如下面的代码),然后我可以根据路由在App.js中设置一个变量。

打包版本:

"dependencies": {
   "react": "^16.12.0",
   "react-router-dom": "^5.1.2",
}

这是路由器当前所在的App.js代码:

import React from "react";
import { BrowserRouter as Router, Route, Switch, NavLink } from "react-router-dom"
import "./App.css";
import AdminDashboard from "./pages/AdminDashboard"
import UserList from "./pages/UserList"

function App() {

    const routeChange = () => {
        console.log("foo!")
        console.log(window.location.pathname)
    }

    return (
        <>
            <Router onChange={routeChange}>
                <NavLink exact={true} className="nav-link" to="/AdminDashboard">Admin Dashboard</NavLink>
                <NavLink exact={true} className="nav-link" to="/UserList">User List</NavLink>
                <Switch>
                    <Route path="/AdminDashboard" component={AdminDashboard} exact />
                    <Route path="/UserList" component={UserList} exact />
                </Switch>
            </Router>
        </>
    );
}

export default App;

3 个答案:

答案 0 :(得分:4)

withRouter包装可以很好地工作,但是从react-router5来看,它们有避免使用的钩子。这样我们就不会向组件注入不需要的道具。 在这种情况下,您可以使用useLocation钩子。

如果您尝试在 App.js 中运行const location = useLocation(),则会得到:"TypeError: useContext(...) is undefined" on line 712 of react-router/esm/react-router.js。但是您可以在子组件(例如 Route.js )中访问useLocation(),并通过prop函数setPathname() <Router>将位置传递回父对象位于父组件中,以便useLocation()起作用。

App.js

import React, { useEffect } from "react"
import { BrowserRouter as Router, NavLink} from "react-router-dom"
import "./App.css"

function App() {
    
    const setPathname = (pathname) => {
        console.log("**", pathname)
    }

    return (
        <>
            <NavLink exact={true} className="nav-link" to="/AdminDashboard">Admin Dashboard</NavLink>
            <NavLink exact={true} className="nav-link" to="/UserList">User List</NavLink>            
            <Router onChange={routeChange}>
                <Routes setPathname={setPathname} />
            </Router>
        </>
    );
}

export default App

Routes.js

import React from "react"
import { Router, Route, Switch, NavLink, useLocation } from "react-router-dom"
import AdminDashboard from "./pages/AdminDashboard"
import UserList from "./pages/UserList"

function Routes(props) {
    const location = useLocation()
    
    useEffect(() => {
        console.log("*", location.pathname)
        props.setPathname(location.pathname)
    },[location])

    return (
        <>
            <Switch>
                <Route path="/AdminDashboard" component={AdminDashboard} exact />
                <Route path="/UserList" component={UserList} exact />
            </Switch>
        </>
    );
}

export default Routes

此操作的结果将为您提供两个控制台日志。一个来自子Routes.js,另一个来自父App.js。然后,您可以根据需要在任一组件中基于pathname设置变量。

  1. *, [pathname]
  2. **, [pathname]

答案 1 :(得分:1)

我认为您需要使用withRouter将路由器绑定到组件中。

withRouter会在渲染后将更新的匹配,位置和历史道具传递给包装的组件。

https://reacttraining.com/react-router/web/api/withRouter

答案 2 :(得分:0)

props.history.listen上分配回调,history属性将检测到更改并触发您的回调

相关问题