What is withRouter for in react-router-dom?
ReactjsReact RouterReactjs Problem Overview
I've sometimes seen people wrap their components in withRouter
when they are exporting them:
import { withRouter } from 'react-router-dom';
class Foo extends React.Component {
// ...
}
export default withRouter(Foo);
What is this for, and when should I use it?
Reactjs Solutions
Solution 1 - Reactjs
When you include a main page component in your app, it is often wrapped in a <Route>
component like this:
<Route path="/movies" component={MoviesIndex} />
By doing this, the MoviesIndex
component has access to this.props.history
so it can redirect the user with this.props.history.push
.
Some components (commonly a header component) appear on every page, so are not wrapped in a <Route>
:
render() {
return (<Header />);
}
This means the header cannot redirect the user.
To get around this problem, the header component can be wrapped in a withRouter
function, either when it is exported:
export default withRouter(Header)
This gives the Header
component access to this.props.history
, which means the header can now redirect the user.
Solution 2 - Reactjs
withRouter
is a higher order component that will pass closest route's match
, current location
, and history
props to the wrapped component whenever it renders. simply it connects component to the router.
Not all components, especially the shared components, will have the access to such router's props. Inside its wrapped components, you would be able to access location
prop and get more information like location.pathname
or redirect the user to different url using this.props.history.push
.
Here's a complete example from their github page:
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);
More information could be found here.
Solution 3 - Reactjs
withRouter
higher-order component allows you to get access to the history
object’s properties and the closest <Route>
's match. withRouter
will pass updated match
, location
, and history
props to the wrapped component whenever it renders.
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);
Solution 4 - Reactjs
withRouter is a higher-order component that will pass the closest route's to get access to some property as to location and match from the props it can be accessed only if give the component the property located in the component
<Route to="/app" component={helo} history ={history} />
and same the match and location prosperity to be able to change the location and used this.props.history.push it should be provided for each component property must provide but when used WithRouter it can be access to location and match without add property history it can be accessed direction without add property history fro each Route.
Solution 5 - Reactjs
it is a higher order component which will pass updated match, location, and history props to the wrapped component whenever it renders.
but I think it has been deprecated via react-router V6.in case of using its property you can use both useLocation
or usenavigate
hooks.
here is a tiny higher order component which use these two hooks in order to implement behavior of withRouter
:
export function withRouter(children){
return(props)=>{
const location = useLocation();
const navigate = usenaviogate();
return <Children {...props} navigate = {navigate} location = {location}
/>
}
}
Solution 6 - Reactjs
By default react router doesn't pass its all information to the component we are refering to
eg - if we are having a route on a component Like below
<Route path="/details/:id">
<Details />
</Route>
and we want to get some props from Route so for that we will have to use withRouter To use it we will have to import it first by
import { withRouter } from "react-router-dom";
and then use it while exporting the component
export default withRouter(Details);