Для чего нужен роутер в реакции-роутере-дом?

Я иногда видел, как люди оборачивают свои компоненты в withRouter когда они экспортируют их:

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

class Foo extends React.Component {
  // ...
}

export default withRouter(Foo);

Для чего это нужно и когда мне его использовать?

Ответ 1

Когда вы включаете компонент главной страницы в свое приложение, он часто оборачивается в компонент <Route> например так:

<Route path="/movies" component={MoviesIndex} />

Благодаря этому компонент MoviesIndex получает доступ к this.props.history поэтому он может перенаправить пользователя с помощью this.props.history.push.

Некоторые компоненты (обычно компонент заголовка) появляются на каждой странице, поэтому они не помещаются в <Route>:

render() {
  return (<Header />);
}

Это означает, что заголовок не может перенаправить пользователя.

Чтобы обойти эту проблему, компонент заголовка может быть обернут в функцию withRouter, либо когда он экспортируется:

export default withRouter(Header)

Это дает компоненту Header доступ к this.props.history, что означает, что заголовок теперь может перенаправлять пользователя.

Ответ 2

withRouter - это компонент более высокого порядка, который будет передавать наиболее близкое match маршрута, текущее location и реквизиты history в обернутый компонент всякий раз, когда он рендерится. просто он подключает компонент к маршрутизатору.

Не все компоненты, особенно общие, будут иметь доступ к таким реквизитам маршрутизатора. Внутри его обернутые компоненты, вы могли бы получить доступ к location пропеллер и получить более подробную информацию, как location.pathname или перенаправить пользователя на другую страницу с помощью this.props.history.push.

Вот полный пример со страницы github:

import React from "react";
import PropTypes from "prop-types";
import { withRouter } from "react-router";

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  };

  render() {
    const { match, location, history } = this.props;

    return <div>You are now at {location.pathname}</div>;
  }
}

// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation);

Более подробную информацию можно найти здесь.