【问题标题】:React Routing: Detect route changeReact Routing:检测路由变化
【发布时间】:2020-06-11 22:31:00
【问题描述】:

我在使用 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;

【问题讨论】:

  • 你试过this吗?并删除 Router 标签上的 onChange 事件,这是没有意义的。
  • props.history 未定义。

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


【解决方案1】:

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() &lt;Router&gt; 必须在父组件中让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]

【讨论】:

  • 这比我的回答更简洁直观=)
  • 我已经尝试过这种方法,但是当我运行“const location = useLocation()”时出现错误:“TypeError: useContext(...) is undefined” on line 712 of react-路由器/esm/react-router.js
  • 这是因为该组件中未设置 react-router 上下文。由于它是设置上下文的 组件,因此您可以在子组件中使用 useHistory,但不能在该子组件中使用。抱歉,我之前没有注意到这一点。更新了我的答案。请检查
  • 将路由移动到子组件,然后通过 props 函数将它们发送回父组件效果很好。我澄清了这一点,并添加了关于我在之前评论中提到的错误的信息,其中的编辑正在等待社区批准。
  • 更改前后如何获取?
【解决方案2】:

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

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

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

【讨论】:

  • 是的,这是选项之一,也可以在历史道具上操作或使用钩子
【解决方案3】:

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

【讨论】:

  • props.history 未定义。
  • history 属性在传递给 Route 的每个组件中,所以我不太确定是什么情况,您可以尝试 import { createBrowserHistory } from 'history'; const history = createBrowserHistory() 并分配该 history 的监听函数
猜你喜欢
  • 2018-01-04
  • 1970-01-01
  • 2017-12-27
  • 2019-11-27
  • 1970-01-01
  • 2018-12-29
  • 2016-04-12
  • 2017-01-01
  • 2021-05-26
相关资源
最近更新 更多