У меня иногда видел люди оборачивают свои компоненты в withRouter, когда экспортируют их:
import { withRouter } from 'react-router-dom';
class Foo extends React.Component {
// ...
}
export default withRouter(Foo);
Для чего это нужно и когда мне следует его использовать?





Когда вы включаете компонент главной страницы в свое приложение, он часто оборачивается компонентом <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, что означает, что заголовок теперь может перенаправлять пользователя.
Кроме того, если вам нужны <Link> и <NavLink> от маршрутизатора, необходимо использовать withRouter HOC.
Думаю, ответ был бы более полным, если бы упомянули, почему history или match не присутствуют по умолчанию? т.е. почему withRouter следует указывать прямо?
что, если мы обернем компонент приложения BrowserRouter в index.js, тогда нам вообще не потребуется withRouter, пожалуйста, предложите?
withRouter - это компонент более высокого порядка, который будет передавать свойства ближайшего маршрута match, текущие location и history обернутому компоненту при каждом рендеринге. просто подключает компонент к роутеру.
Не все компоненты, особенно общие компоненты, будут иметь доступ к таким свойствам маршрутизатора. Внутри его обернутых компонентов вы сможете получить доступ к опоре location и получить дополнительную информацию, например location.pathname, или перенаправить пользователя на другой URL-адрес с помощью 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);
Более подробную информацию можно найти здесь.
withRouter - это компонент более высокого порядка, который будет передавать ближайший маршрут, чтобы получить доступ к некоторому свойству в отношении местоположения и совпадения с реквизитами, к нему можно получить доступ, только если дать компоненту свойство, расположенное в компоненте
<Route to = "/app" component = {helo} history = {history} />
и то же самое соответствие и процветание местоположения, чтобы иметь возможность изменить местоположение и использовать this.props.history.push, он должен быть предоставлен для каждого свойства компонента, которое должно обеспечивать, но при использовании WithRouter он может иметь доступ к местоположению и сопоставлению без добавления истории свойств. можно получить доступ к направлению без добавления истории свойств для каждого маршрута.
Компонент высшего порядка withRouter позволяет получить доступ к свойствам объекта history и ближайшему соответствию <Route>. withRouter будет передавать обновленные свойства match, location и history обернутому компоненту при каждом рендеринге.
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);
Подробнее об этом здесь - reacttraining.com/react-router/core/api/withRouter
то же самое с useRouteMatch / useHistory / useLocation при использовании функциональных компонентов?
это компонент более высокого порядка, который будет передавать обновленные свойства соответствия, местоположения и истории обернутому компоненту при каждом рендеринге.
но я думаю, что он устарел через реактивный маршрутизатор V6. в случае использования его свойства вы можете использовать как хуки useLocation, так и usenavigate.
вот крошечный компонент более высокого порядка, который использует эти два перехватчика для реализации поведения withRouter:
export function withRouter(children){
return(props)=>{
const location = useLocation();
const navigate = usenaviogate();
return <Children {...props} navigate = {navigate} location = {location}
/>
}
}
По умолчанию реагирующий маршрутизатор не передает всю информацию компоненту, на который мы ссылаемся.
например - если у нас есть маршрут для компонента, как показано ниже
<Route path = "/details/:id">
<Details />
</Route>
и мы хотим получить некоторые реквизиты от Route, поэтому для этого нам придется использовать withRouter Чтобы использовать его, нам нужно сначала импортировать его
import { withRouter } from "react-router-dom";
а затем использовать его при экспорте компонента
export default withRouter(Details);
Как указано в @ msoliman ответ,
withRouterтакже предоставляет доступ кmatchиlocation. Было бы неплохо, если бы в принятом ответе упоминалось это, поскольку перенаправление пользователя - не единственный вариант использованияwithRouter. В остальном это хорошая самооценка.