Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to expose route params outside <Route> component?

If I have something like this:

<ConnectedRouter history={history}>
    <App />
</ConnectedRouter>

My routes config looks like:

export default [{
    path: '/',
    exact: true,
    main: Home
}, 
{
    path: '/:someId',
    exact: true,
    main: Profile
},
{
    path: '*',
    main: NotFound
}];

Where app is just a wrapper of the routes and other components like:

class App extends Component {
render() {
return (
  <div>
    <Header />
    <Switch>
      {routes.map((route, i) => <Route exact key={i} component={route.main} path={route.path}/>)}
    </Switch>
    <AnotherComponent {...this.props} />
  </div>
);
}
}

Is there a way for AnotherComponent to use match.params or to expose those? I already tried wrapping the component with withRouter and also adding it as a Route with no path to match like:

<Route component={AnotherComponent} />

And when the route is /:someId it does render both Profile and AnotherComponent, but match.params for AnotherComponent are empty :/.

Is this possible? Thanks!

like image 302
gl0gl0 Avatar asked Jun 27 '17 14:06

gl0gl0


People also ask

What is render in route?

render: funcInstead of having a new React element created for you using the component prop, you can pass in a function to be called when the location matches. The render prop function has access to all the same route props (match, location and history) as the component render prop.

What is the different between render and component in the route component?

render makes the component mount just once, then re-render when required. The component stays in the background — this means that anything you put in componentDidMount , constructor , or, for example, shouldComponentUpdate , will run only once!

How do you use useRouteMatch in react Dom v6 router?

When using React Router v5, it was possible to get the path (pattern) for that route using useRouteMatch . const { path } = useRouteMatch(); React Router v6 offers a similar hook, useMatch ; however this expects to receive the pattern you want to match against.


2 Answers

Edit: You can use https://v5.reactrouter.com/web/api/Hooks/useroutematch directly these days.

Original Answer

You can use matchPath

import { matchPath } from 'react-router'
import { useLocation } from 'react-router-dom'

 //----
const { pathname } = useLocation()

const params =  matchPath(pathname, { path:"/:someId" })
 //----

like image 191
Haseeb A Avatar answered Sep 21 '22 16:09

Haseeb A


React router will only return params if you have a path on the Route. You can pass down the params from your top level . Have that component render inside of it. It will have access to the params. As for any other time, you need to be doing:

<Route  path="/:someId" component={AnotherComponent} />

If you want it to actually get that param!

Only children underneath the Route component can access the params. You should be building your app in such a way that only the component inside that route needs its params.

like image 38
zackify Avatar answered Sep 22 '22 16:09

zackify