React router 4 history.listen 永远不会触发

Posted

技术标签:

【中文标题】React router 4 history.listen 永远不会触发【英文标题】:React router 4 history.listen never fires 【发布时间】:2017-10-21 02:25:02 【问题描述】:

切换到路由器 v4 和历史 v4.5.1,现在历史监听器不工作

import createBrowserHistory from 'history/createBrowserHistory'
const history = createBrowserHistory()

history.listen((location, action) => 
  console.log(action, location.pathname, location.state)  //  <=== Never happens
)

render(
  <Provider store=store>
    <Router history=history>
      ...
    </Router>
  </Provider>,
  document.getElementById('root')
)

任何想法为什么它被忽略?

【问题讨论】:

您在这里使用的路由器是什么?是浏览器路由器还是路由器?我问这个是因为有些人用这样的命名导入导入 BrowserRouter。 import BrowserRouter as Router from 'react-router-dom' ^ 这就是我正在做的事情 【参考方案1】:

由于您使用的是 BrowserRouter(使用问题的 cmets 中提到的导入别名路由器),它并不关心您传入的历史记录。取而代之的是 internally creates and assigns new browser history to the Router。所以你在Router中监听和使用的历史实例是不一样的。这就是你的监听器不起作用的原因。

导入原始路由器。

import  Router  from 'react-router-dom';

它将按您的预期工作。

【讨论】:

“原始路由器”是v3。我使用的是 v4,没有'react-router',只有'react-router-dom'BrowserRouter HashRouter 但是,您仍然可以从“react-router-dom”导入路由器。试试import Router from 'react-router-dom'; 它应该可以工作。 仍然没有区别 猜不出是什么原因。但它对我有用codesandbox.io/s/9WrAYvjP 我可以确认这也适用于 React Router v4。【参考方案2】:

问题是您正在创建自己的历史对象并将其传递给路由器。但是,React Router v4 已经通过 this.props 为您提供了这个对象。 (导入Router与此无关)

componentDidMount() 
    this.props.history.listen((location, action) => console.log('History changed!', location, action));

您可能需要对您的应用进行更多分层,如下所示,并将此 componentDidMount 方法放在您的 MyApp.jsx 中,而不是直接放在最顶层.

<Provider store=store>
    <BrowserRouter>
        <MyApp/>
    </BrowserRouter>
</Provider>

(如果你在做 React Native,或者使用 NativeRouter 而不是 BrowserRouter)

【讨论】:

坚持使用 BrowserRouter 解决方案,要访问历史记录,可以在路由器上创建一个 ref 并继续通过 componentDidMount 或 useEffect 在 BrowseRouter 上方的级别上进行侦听。这样就不需要在 BrowserRouter 下添加额外的组件层了。【参考方案3】:

像魔术一样工作:?‍♂️?‍♂️?‍♂️

const history = useHistory();      
    
     useEffect(() => 
            if (history)  // for jest sake ))
                history.listen(() => 
                    store.reset();
                );
            
     , []);

【讨论】:

以上是关于React router 4 history.listen 永远不会触发的主要内容,如果未能解决你的问题,请参考以下文章

[react-router] React-Router 3和React-Router 4有什么变化?添加了什么好的特性?

[react-router] React-Router 4中<Router>组件有几种类型?

react-router 4.0踩到的坑

react-router4.x

react-router 4.0的初探

react-router 4 的使用