使用 ReactDOM.render 添加链接作为路由器的子级会产生“您不应在 <Router> 之外使用 <Link>”

Tim*_*ton 4 leaflet reactjs react-router react-router-v4 react-router-dom

我正在寻找一种在反应路由器内ReactDOM.render创建的方法。Link设置或多或少看起来像这样:

const router = (
  <div>
    <Router>
      <Route path="/map" component={Map}/>
    </Router>
  </div>
);
Run Code Online (Sandbox Code Playgroud)

的相关部分Map.jsx如下所示:

const MapPopup = () => {
  return (
    <Link to={`/map/add`} />
  )
}

class Map extends React.Component {

  componentDidMount() {
    this.map = L.map('map')

    //...stuff...

    this.map.on('contextmenu', event => {
      popup
        .setLatLng(event.latlng)
        .addTo(this.map)
        .setContent(
          ReactDOM.render(
            MapPopup(),
            document.querySelector('.leaflet-popup-content')
          )[0]
        )
        .openOn(this.map)
    })
  }


  render() {
    return (
      <React.Fragment>
        <div id="map" />
      </React.Fragment>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

我基本上是想Link在传单提供的地图弹出窗口中添加一个(我不能在这个项目中使用react-leaflet)。但是,如果我直接在渲染函数中返回 MapPopup,它就会起作用(显然不在弹出窗口中,但链接确实可以这样工作)。

<React.Fragment>
    <div id="map" />
    <MapPopup />
</React.Fragment>
Run Code Online (Sandbox Code Playgroud)

有谁知道我如何解决这个相当不寻常的问题?

我在用"react-router-dom": "4.3.1"

Vad*_*hev 5

这是预期的错误,因为<Link>组件期望祖先组件是路由器类型(<BrowserRouter>, <MemoryRouter>, <Router>... ),请参阅此线程以获取更多详细信息。

ReactDOM.createPortal对于您的场景,可以使用以下方法来规避此限制ReactDOM.render

<Route
    path="/popup"
    render={() => (
              <Popup>
                <div>
                  Some content goes here
                  <Link to="/map"> Back to map</Link>
                </div>
             </Popup>
          )}
/>
Run Code Online (Sandbox Code Playgroud)

在哪里

class Popup extends React.Component {
  render() {
    return ReactDOM.createPortal(
      this.props.children,
      document.querySelector("#link-render-div")
    );
  }
} 
Run Code Online (Sandbox Code Playgroud)

这是一个演示供您参考