Reputation: 19967
I'd like to display a title
in <AppBar />
that is somehow passed in from the current route.
In React Router v4, how would <AppBar />
be able to get the current route passed into it's title
prop?
<Router basename='/app'>
<main>
<Menu active={menu} close={this.closeMenu} />
<Overlay active={menu} onClick={this.closeMenu} />
<AppBar handleMenuIcon={this.handleMenuIcon} title='Test' />
<Route path='/customers' component={Customers} />
</main>
</Router>
Is there a way to pass a custom title from a custom prop
on <Route />
?
Upvotes: 430
Views: 674015
Reputation: 459
React Router Version 6
<Link to="/myuser?page=10#myHash">User</Link>
Use useLocation hook to get location object
const location = useLocation();
console.log('hash', location.hash); // #myHash
console.log('pathname', location.pathname); // /myuser
console.log('search', location.search); // ?page=10
Upvotes: 2
Reputation: 207
1. First Warp App Component
// index.js
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
2. Import useLocation Hook and get path name
// App.js
import {Routes, useLocation } from "react-router-dom";
function App() {
const location = useLocation();
// Get current path
const path = location.pathname;
return (
<>
<Routes>
<Components currentPath={path} />
</Routes>
</>
);
}
location.pathname
returns path name, use it as required.
Upvotes: -1
Reputation: 9652
In the 5.1 release of react-router there is a hook called useLocation, which returns the current location object. This might useful any time you need to know the current URL.
import { useLocation } from 'react-router-dom'
function HeaderView() {
const location = useLocation();
console.log(location.pathname);
return <span>Path : {location.pathname}</span>
}
Upvotes: 521
Reputation: 67
Add
import {withRouter} from 'react-router-dom';
Then change your component export
export default withRouter(ComponentName)
Then you can access the route directly within the component itself (without touching anything else in your project) using:
window.location.pathname
Tested March 2020 with: "version": "5.1.2"
Upvotes: 5
Reputation: 18392
There's a hook called useLocation in react-router v5, no need for HOC or other stuff, it's very succinctly and convenient.
import { useLocation } from 'react-router-dom';
const ExampleComponent: React.FC = () => {
const location = useLocation();
return (
<Router basename='/app'>
<main>
<AppBar handleMenuIcon={this.handleMenuIcon} title={location.pathname} />
</main>
</Router>
);
}
Upvotes: 84
Reputation: 629
Has Con Posidielov said, the current route is present in this.props.location.pathname
.
But if you want to match a more specific field like a key (or a name), you may use matchPath to find the original route reference.
import { matchPath } from `react-router`
const routes = [{
key: 'page1'
exact: true,
path: '/page1/:someparam/',
component: Page1,
},
{
exact: true,
key: 'page2',
path: '/page2',
component: Page2,
},
]
const currentRoute = routes.find(
route => matchPath(this.props.location.pathname, route)
)
console.log(`My current route key is : ${currentRoute.key}`)
Upvotes: 37
Reputation: 496
Here is a solution using history
Read more
import { createBrowserHistory } from "history";
const history = createBrowserHistory()
inside Router
<Router>
{history.location.pathname}
</Router>
Upvotes: 37
Reputation: 2547
In react router 4 the current route is in -
this.props.location.pathname
.
Just get this.props
and verify.
If you still do not see location.pathname
then you should use the decorator withRouter
.
This might look something like this:
import {withRouter} from 'react-router-dom';
const SomeComponent = withRouter(props => <MyComponent {...props}/>);
class MyComponent extends React.Component {
SomeMethod () {
const {pathname} = this.props.location;
}
}
Upvotes: 252
Reputation: 7549
If you are using react's templates, where the end of your react file looks like this: export default SomeComponent
you need to use the higher-order component (often referred to as an "HOC"), withRouter
.
First, you'll need to import withRouter
like so:
import {withRouter} from 'react-router-dom';
Next, you'll want to use withRouter
. You can do this by change your component's export. It's likely you want to change from export default ComponentName
to export default withRouter(ComponentName)
.
Then you can get the route (and other information) from props. Specifically, location
, match
, and history
. The code to spit out the pathname would be:
console.log(this.props.location.pathname);
A good writeup with additional information is available here: https://reacttraining.com/react-router/core/guides/philosophy
Upvotes: 91
Reputation: 129
I think the author's of React Router (v4) just added that withRouter HOC to appease certain users. However, I believe the better approach is to just use render prop and make a simple PropsRoute component that passes those props. This is easier to test as you it doesn't "connect" the component like withRouter does. Have a bunch of nested components wrapped in withRouter and it's not going to be fun. Another benefit is you can also use this pass through whatever props you want to the Route. Here's the simple example using render prop. (pretty much the exact example from their website https://reacttraining.com/react-router/web/api/Route/render-func) (src/components/routes/props-route)
import React from 'react';
import { Route } from 'react-router';
export const PropsRoute = ({ component: Component, ...props }) => (
<Route
{ ...props }
render={ renderProps => (<Component { ...renderProps } { ...props } />) }
/>
);
export default PropsRoute;
usage: (notice to get the route params (match.params) you can just use this component and those will be passed for you)
import React from 'react';
import PropsRoute from 'src/components/routes/props-route';
export const someComponent = props => (<PropsRoute component={ Profile } />);
also notice that you could pass whatever extra props you want this way too
<PropsRoute isFetching={ isFetchingProfile } title="User Profile" component={ Profile } />
Upvotes: 12