设置 React Router 历史监听器的正确位置
Proper place to setup React Router history listener
我正在尝试在最顶层设置一个历史监听器,以便每次位置发生变化时,都会执行一些代码(Google 在我的案例中是分析跟踪)。
目前,我的 App.js 看起来像这样:
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/" component={MainLayout}/>
</Switch>
</BrowserRouter>
);
}
据我了解,我只能在BrowserRouter
里面使用history
,但是它只能有一个child,所以我只能把它放在Switch
里面,但是我必须将它放在 Switch 下的每个组件中,我不能这样做,因为我只希望它 运行 一次。如果我只是在 Switch
下添加自定义组件而不将其包装到 Router
中,则没有历史记录。
我应该更改什么才能使其正常工作?是否可以在 App.js
代码中获取 history
的实例?是否可以使用自定义组件或 HOC 来实现?
可以使用 history
包,而不是依赖 React router 创建的默认包。
例如,使用history.listen
:
history.listen((location) => {
ReactGA.pageview(location.pathname + window.location.search);
});
在我的示例中,我使用 react-ga
作为跨项目标准化我们的 GA 工具的一种方式。
您需要添加一个 Route
,它将无条件呈现。
尝试这样的事情:
render() {
return (
<BrowserRouter>
<React.Fragment>
<Route component={HistoryListenerComponent}/>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/" component={MainLayout}/>
</Switch>
</React.Fragment>
</BrowserRouter>
);
}
所以 HistoryListenerComponent
总是被渲染,你可以 listen
从它的 componentDidMount
.
发现最简单的选项是更新组件 -- https://github.com/pshrmn/rrc/blob/master/docs/OnUpdate.md
以下是对我有用的方法:
import {withRouter} from 'react-router-dom';
现在只需像这样用 withRouter 包裹你使用 React-ga 的组件:
componentDidMount=()=>{
ReactGa.initialize('00000'); //enter id
ReactGa.pageview(window.location.pathname + window.location.search);
this.props.history.listen(location => {
ReactGa.set({ page: location.pathname }); // Update the user's current page
ReactGa.pageview(location.pathname); // Record a pageview for the given page
});
}
render (){
return (
<Switch>
<Route ....>
.....
<Switch>
);
}
export default withRouter(ComponentName)
记住没有包装 withRouter ,你不能使用 this.props.history 属性。
您不能将自定义历史侦听器用于 BrowserRouter 组件。它有一个内置的历史道具(即 this.props.history)。
我正在尝试在最顶层设置一个历史监听器,以便每次位置发生变化时,都会执行一些代码(Google 在我的案例中是分析跟踪)。
目前,我的 App.js 看起来像这样:
render() {
return (
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/" component={MainLayout}/>
</Switch>
</BrowserRouter>
);
}
据我了解,我只能在BrowserRouter
里面使用history
,但是它只能有一个child,所以我只能把它放在Switch
里面,但是我必须将它放在 Switch 下的每个组件中,我不能这样做,因为我只希望它 运行 一次。如果我只是在 Switch
下添加自定义组件而不将其包装到 Router
中,则没有历史记录。
我应该更改什么才能使其正常工作?是否可以在 App.js
代码中获取 history
的实例?是否可以使用自定义组件或 HOC 来实现?
可以使用 history
包,而不是依赖 React router 创建的默认包。
例如,使用history.listen
:
history.listen((location) => {
ReactGA.pageview(location.pathname + window.location.search);
});
在我的示例中,我使用 react-ga
作为跨项目标准化我们的 GA 工具的一种方式。
您需要添加一个 Route
,它将无条件呈现。
尝试这样的事情:
render() {
return (
<BrowserRouter>
<React.Fragment>
<Route component={HistoryListenerComponent}/>
<Switch>
<Route path="/" exact component={Home}/>
<Route path="/" component={MainLayout}/>
</Switch>
</React.Fragment>
</BrowserRouter>
);
}
所以 HistoryListenerComponent
总是被渲染,你可以 listen
从它的 componentDidMount
.
发现最简单的选项是更新组件 -- https://github.com/pshrmn/rrc/blob/master/docs/OnUpdate.md
以下是对我有用的方法:
import {withRouter} from 'react-router-dom';
现在只需像这样用 withRouter 包裹你使用 React-ga 的组件:
componentDidMount=()=>{
ReactGa.initialize('00000'); //enter id
ReactGa.pageview(window.location.pathname + window.location.search);
this.props.history.listen(location => {
ReactGa.set({ page: location.pathname }); // Update the user's current page
ReactGa.pageview(location.pathname); // Record a pageview for the given page
});
}
render (){
return (
<Switch>
<Route ....>
.....
<Switch>
);
}
export default withRouter(ComponentName)
记住没有包装 withRouter ,你不能使用 this.props.history 属性。 您不能将自定义历史侦听器用于 BrowserRouter 组件。它有一个内置的历史道具(即 this.props.history)。