Добавление ссылки как дочернего элемента маршрутизатора с ReactDOM.render приводит к «Вы не должны использовать <Link>вне <Router>» - PullRequest
2 голосов
/ 19 мая 2019

Я ищу способ использования ReactDOM.render для создания Link в реагирующем маршрутизаторе. Настройка более или менее выглядит следующим образом:

const router = (
  <div>
    <Router>
      <Route path="/map" component={Map}/>
    </Router>
  </div>
);

Соответствующие части 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>
    )
  }
}

Я в основном пытаюсь добавить Link к всплывающему окну карты, предоставленному буклетом (я не могу использовать реактив-буклет для этого проекта). Однако, если я возвращаю MapPopup непосредственно в функцию рендеринга, это работает (очевидно, не во всплывающем окне, но Ссылка работает таким образом).

<React.Fragment>
    <div id="map" />
    <MapPopup />
</React.Fragment>

У кого-нибудь есть идеи, как мне решить эту довольно необычную проблему?

Я использую "react-router-dom": "4.3.1".

1 Ответ

1 голос
/ 20 мая 2019

Это ожидаемая ошибка, поскольку компонент <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>
          )}
/>

, где

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

и

Вот демо для вашей справки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...