Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: New hook "useChildRoutePath()" to get the current route "path" value. #8555

Closed
Jaygiri opened this issue Jan 4, 2022 · 3 comments
Labels

Comments

@Jaygiri
Copy link

Jaygiri commented Jan 4, 2022

What is the new or updated feature that you are suggesting?

I am suggesting a new hook called useChildRoutePath(). This hook will return the route path value of current route.

Why should this feature be included?

Nesting Route is very intuitive. With that using Outlet makes it perfect setup.

Mostly you have a wrapper component for Outlet like this:

const Layout = () => {
  return (
    <Outlet/>
  )
}

Now, if Layout component wants to know what is being rendered in Outlet only way (I know) is to use useLocation hook to get pathname. Layout can parse the pathname value and apply the business logic based on it.

const Layout = () => {
  const { pathname } = useLocation();
  // parse the 'pathname' to get path value for current route being rendered in Outlet
  return (
    <Outlet/>
  )
}

However, pathname parsing becomes complicated if routes are nested and Layout just needs to know the route.path value.
Also if Layout position is moved in the nested hierarchy of routes the custom parsing of route.path needs to be updated.

This sample solution might work for some very simple nested routes but failed for complex routes with dynamic path values (eg. path=":id/messages")

// we can pass parent path to Layout in the routes configuration
// remember to update parentPath value if you change the position of Layout in routes config
const Layout = ({parentPath}) => {
  const { pathname } = useLocation();
  const path = pathname.replace(parentPath, ""):
  // do something with 'path'
  return (
    <Outlet/>
  )
}

Using suggested hook though everything becomes easy!

const Layout = () => {
  const path = useChildRoutePath();
  // do something with 'path'
  return (
    <Outlet/>
  )
}

Please take a look at this question for a detailed use case (with actual requirement):
https://stackoverflow.com/questions/70576327/how-to-get-child-route-path-with-react-router-v6

Let me know if I can provide more information or if there is solution already.

@Jaygiri Jaygiri added the feature label Jan 4, 2022
@timdorr
Copy link
Member

timdorr commented Jan 4, 2022

Unfortunately, this isn't possible for a number of reasons. Most notably is which child you mean under the current Route. If you have many layers of nesting, the "child route" becomes a set of routes. Or if you have other Routes in your component tree, then it becomes a multi-dimensional set of children over different route groups.

Since your SO question mentions animations, I think what you're looking for will be answered by #8008, whenever that lands. I'd watch that topic for updates.

@timdorr timdorr closed this as completed Jan 4, 2022
@MeiKatz
Copy link
Contributor

MeiKatz commented Jan 4, 2022

@timdorr I guess it's a little bit easier than you think, because we know which <Route /> is the clothes parent component of the current element. Therefore we know the path up to the calling component. And therefore we also know the sub-path of the current chosen child component.

@iDm1
Copy link

iDm1 commented Nov 1, 2023

Ability to know what route path is rendered in would be very helpful.

Path of one direct child is enough for example to decide to render the or current path or both.

const router = createBrowserRouter([
{
    path: 'parent',
    element: <Parent/>,
    children: [
        {
            path: ':id/child',
            element: <Child/>,
        },
        {
            path: 'details',
            element: <Details/>,
        },
    ],
  },
])

Something like:

import { outletPathMatch } from 'react-router-dom'

if (outletPathMatch(':id/child')) {
  return <Outlet/>
} else {
  return (
    <>
       <OtherElement/>
       <Outlet/>
    </>
  )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants