我有几个按钮作为路径。每次改变路线时,我都想确保激活的按钮发生了变化。

有没有办法在react路由器v4中监听路由变化?


当前回答

用钩子:

import { useEffect } from 'react'
import { withRouter } from 'react-router-dom'
import { history as historyShape } from 'react-router-prop-types'

const DebugHistory = ({ history }) => {
  useEffect(() => {
    console.log('> Router', history.action, history.location)
  }, [history.location.key])

  return null
}

DebugHistory.propTypes = { history: historyShape }

export default withRouter(DebugHistory)

导入并呈现为<DebugHistory>组件

其他回答

您应该使用history v4 lib。

这里的例子

history.listen((location, action) => {
  console.log(`The current URL is ${location.pathname}${location.search}${location.hash}`)
  console.log(`The last navigation action was ${action}`)
})

要在上面的基础上展开,您需要获取history对象。如果您正在使用BrowserRouter,您可以导入withRouter并使用高阶组件(HoC)包装您的组件,以便通过道具访问历史对象的属性和函数。

    import { withRouter } from 'react-router-dom';

    const myComponent = ({ history }) => {

        history.listen((location, action) => {
            // location is an object like window.location
            console.log(action, location.pathname, location.state)
        });

        return <div>...</div>;
    };

    export default withRouter(myComponent);

唯一需要注意的是,使用throuter和大多数其他访问历史的方法似乎会污染道具,因为它们将对象解构到其中。

正如其他人所说,这已经被react路由器暴露的钩子所取代,并且它有内存泄漏。如果你在一个函数组件中注册监听器,你应该通过useEffect来做,然后在函数的返回中取消注册。

v5.1引入了有用的钩子useLocation

https://reacttraining.com/blog/react-router-v5-1/#uselocation

import { Switch, useLocation } from 'react-router-dom'

function usePageViews() {
  let location = useLocation()

  useEffect(
    () => {
      ga.send(['pageview', location.pathname])
    },
    [location]
  )
}

function App() {
  usePageViews()
  return <Switch>{/* your routes here */}</Switch>
}

使用useEffect钩子,可以在不添加侦听器的情况下检测路由更改。

import React, { useEffect }           from 'react';
import { Switch, Route, withRouter }  from 'react-router-dom';
import Main                           from './Main';
import Blog                           from './Blog';


const App  = ({history}) => {

    useEffect( () => {

        // When route changes, history.location.pathname changes as well
        // And the code will execute after this line

    }, [history.location.pathname]);

    return (<Switch>
              <Route exact path = '/'     component = {Main}/>
              <Route exact path = '/blog' component = {Blog}/>
            </Switch>);

}

export default withRouter(App);

import React, { useEffect } from 'react';
import { useLocation } from 'react-router';

function MyApp() {

  const location = useLocation();

  useEffect(() => {
      console.log('route has been changed');
      ...your code
  },[location.pathname]);

}

用钩子