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

IT技术 reactjs redux react-router browser-history react-router-v4
2021-05-20 09:01:49

切换到路由器 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')
)

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

3个回答

由于您使用的是 BrowserRouter(使用问题评论中提到的导入别名 Router),它不关心您传入的 history 属性。而不是它在内部创建新的浏览器历史记录并将其分配给 Router所以你监听的和在 Router 中使用的历史实例是不一样的。这就是为什么你的听众不起作用。

导入原始路由器。

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

它会按您的预期工作。

问题在于您正在创建自己的历史对象并将其传递到路由器中。然而,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)

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

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