React Router Link 不适用于 LeafletJS

React Router Link doesn#39;t work with LeafletJS(React Router Link 不适用于 LeafletJS)
本文介绍了React Router Link 不适用于 LeafletJS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!



  • react-router-dom 4.1.1
  • react-router-redux 5.0.0-alpha.4
  • 反应传单 1.1.3
  • 传单 1.0.3


我创建了一张传单地图.我在其中添加了一些标记.这些标记有弹出窗口.在每个弹出窗口中,我都希望有一个 <Link>



<应用容器/><ConnectedRouter 历史={历史}>

<菜单容器/><开关><Route path='/:area/:sport/list' 组件={ListContainer}/><路线路径='/:area/:sport/map' 组件={MapContainer}/><Route path='/:area/:sport/rasp' 组件={RaspContainer}/><Route path='/:shortcode/details' 组件={StationDetailsContainer}/><从='/' 重定向到='/wellington/paragliding/list'/><路由组件={NoMatch}/></开关></div></连接路由器></div></提供者>,document.getElementById('root'))






在我的 <MapMode> 中,我使用传单中的 <Map>.如果我在 <Map> 标签上方设置一个 <Link> ,它就可以工作.只要我想在我的 <Map> 中有一个链接,它就会以某种方式中断.这是我页面的 React 结构,<Popup> 标签只包含 null,因为 Javascript 正在破坏:



我不能 100% 确定这个答案.但无论如何我都会尝试,因为我认为至少它可能会为将来尝试解决此问题的任何人提供一些启示.

我从 react 中的 this issue 得到了第一个提示-leaflet GitHub 存储库.根据那个和你的错误,问题似乎是 Popup 无法从 context 访问 router 因为 context 没有传入以他们呈现的方式弹出窗口.因此,如果我们可以将上下文显式传递给 Popup,我们应该能够解决问题.

然后我找到了一种将上下文显式传递到组件中的方法 this StackOverflow 答案.有了这个,我认为你应该能够使用如下的 HoC(高阶组件)来解决你的问题.

这是向组件注入上下文的 HoC:

function withContext(WrappedComponent, context){类 ContextProvider 扩展 React.Component {getChildContext() {返回上下文;}使成为() {返回 <WrappedComponent {...this.props}/>}}ContextProvider.childContextTypes = {};Object.keys(context).forEach(key => {ContextProvider.childContextTypes[key] = React.PropTypes.any.isRequired;});返回上下文提供者;}

假设您在一个名为 MapMaker 的组件中使用 Popup.然后你可以像这样使用 HoC 将带有 router 的上下文注入到 Popup 中.

类 MapMaker 扩展 React.Component {//......//这确保你有路由器 this.context//您还可以添加需要传递到 Popup 的任何其他上下文静态上下文类型 = {路由器:React.PropTypes.object.isRequired}使成为(){const PopupWithContext = withContext(Popup, this.context);返回 (//..... 你的 JSX 在 Popup 之前<PopupWithContext/>//用你的道具//.....弹出后你的JSX);}}


  • react-router-dom 4.1.1
  • react-router-redux 5.0.0-alpha.4
  • react-leaflet 1.1.3
  • leaflet 1.0.3

Steps to reproduce

I create a leaflet map. In which I add some markers. These markers have popups. In each of these popup I want to have a <Link>

Also if it helps this is my Routing config:

  <Provider store={store}>
      <AppContainer />
      <ConnectedRouter history={history}>
          <MenuContainer />
            <Route path='/:area/:sport/list' component={ListContainer} />
            <Route path='/:area/:sport/map' component={MapContainer} />
            <Route path='/:area/:sport/rasp' component={RaspContainer} />
            <Route path='/:shortcode/details' component={StationDetailsContainer} />
            <Redirect exact from='/' to='/wellington/paragliding/list' />
            <Route component={NoMatch} />

Expected Behavior

I can see my link and click on it when popup opens.

Actual Behavior

Impossible to see the link. It's not generated.

Extra details

Inside my <MapMode> I use <Map> from leaflet. If I set a <Link> just above the <Map> tag it works. As soon as I want to have a link inside my <Map>, somehow it breaks. This is the React structure of my page, <Popup> tag just contains null as Javascript is breaking:

It's quite a complex problem so feel free to ask me questions. Thanks.


I'm not 100% sure about this answer. But anyway I'm going to try because I think at least it might shed some light to anyone who will try to solve this problem in future.

I got the first hint from this issue in react-leaflet GitHub repo. According to that and your error, it seems the problem is Popup can't access the router from the context because context isn't passed into the Popup with the way they render it. So we should be able to fix the problem if we can explicitly pass the context to Popup.

Then I found a way to explicitly pass the context into a component in this StackOverflow answer. With that, I think you should be able to use a HoC(Higher order Component) as follows to solve your problem.

This is the HoC that inject context to a component:

function withContext(WrappedComponent, context){

  class ContextProvider extends React.Component {
    getChildContext() {
      return context;

    render() {
      return <WrappedComponent {...this.props} />

  ContextProvider.childContextTypes = {};
  Object.keys(context).forEach(key => {
    ContextProvider.childContextTypes[key] = React.PropTypes.any.isRequired; 

  return ContextProvider;

Let's say you are using Popup inside a component called MapMaker. Then you can inject the context with router into Popup using the HoC like this.

class MapMaker extends React.Component {


  // This make sure you have router in you this.context
  // Also you can add any other context that you need to pass into Popup
  static contextTypes = {
    router: React.PropTypes.object.isRequired


    const PopupWithContext = withContext(Popup, this.context);

    return (
      //..... your JSX before Popup
      <PopupWithContext/> // with your props
      //..... your JSX after Popup


这篇关于React Router Link 不适用于 LeafletJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!



How do I can get a text of all the cells of the table using testcafe(如何使用 testcafe 获取表格中所有单元格的文本)
node_modules is not recognized as an internal or external command(node_modules 未被识别为内部或外部命令)
How can I create conditional test cases using Protractor?(如何使用 Protractor 创建条件测试用例?)
PhantomJS and clicking a form button(PhantomJS 并单击表单按钮)
Clicking #39;OK#39; on alert or confirm dialog through jquery/javascript?(在警报上单击“确定或通过 jquery/javascript 确认对话框?)
QunitJS-Tests don#39;t start: PhantomJS timed out, possibly due to a missing QUnit start() call(QunitJS-Tests 不启动:PhantomJS 超时,可能是由于缺少 QUnit start() 调用)