'React Router v6 useNavigate() doesn't navigate if replacing last element in path

I have a react component with the following function

    const handleNavigate = (clientId) => {
        console.log(clientId)
        navigate(`/dashboard/clients/${clientId}`)
    }

The console.log() is showing the ID I want to append to use in the navigate function.
AND
The URL in the browser is updating.

But the page does not change.

This works to navigate from /dashboard/clients to /dashboard/clients/foo

but it does not work to navigate from /dashboard/clients/foo to /dashboard/clients/bar

The clientId is passed into the card like so...

const CompanyCard = (props) => {
    const { client, showWatchlist, removeDisabled, showRemove, removeType } = props
...
}

then in the card

                <CardActionArea
                    onClick={() => handleNavigate(client._id)}
                 ...

Any ideas?
Thanks

UPDATE

After reading up from @redapollos suggestion I tried Outlet and the

useRoutes methods... neither worked.

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

// then in the routes...

        { path: 'clientdetail/:id', element: <ClientDetail /> },
        { path: 'clientdetail/', element: <ClientDetail /> },

This might be due to using the useRoutes hook but I am still working on it.

Another question here on SO that might get an answer sooner - https://stackoverflow.com/a/70009104/13078911



Solution 1:[1]

Try replacing the URL instead of adding a new one. when you are going from /dashboard/clients to /dashboard/clients/foo you are going from a parent to a child, your URL has everything plus /foo. But, when you are going from /dashboard/clients/foo to /dashboard/clients/bar you are navigating to a sibling /foo to /bar that might be causing the issue. try to replace the value like navigate(/dashboard/clients/ba, {replace: true}) here is example of how to use this in general. use it for more information. https://www.digitalocean.com/community/tutorials/react-react-router-v6

Solution 2:[2]

I had this same issue and my code was fine, however, I found out at this post that optional params aren't supported in v6.
https://github.com/remix-run/react-router/issues/7285

I had:

<Routes>
  <Route path="list/:id?" element={<SystemList />} />
</Routes>

and had to change it to:

<Routes>
  <Route path="list/:id" element={<SystemList />} />
  <Route path="list/" element={<SystemList />} />
</Routes>

I'm hoping they support it in the future but as of v6.0.2 they do not.

Solution 3:[3]

Maybe try the component Navigate:

<Navigate to={<your_path>}/>

Solution 4:[4]

Workable solution!

navigate('/url')
navigate(0)

After replacing the url, manually calling navigate(0) will refresh the page automatically!

This will work in a situation like: navigate from /dashboard/clients/foo to /dashboard/clients/bar

More info:

  1. useNavigate docs

  2. How do I reload a page with react-router?

Solution 5:[5]

I think this is a better work around on this one.

import React from 'react' 
import { useHistory } from 'react-router-dom' 
... 

const history = useHistory() 
const handleNavigate = (clientId) => {
        console.log(clientId)
        history.push(`/dashboard/clients/${clientId}`)
    }

Make sure your app is wrapped in a BrowserRouter from react-router-dom

Solution 6:[6]

Try adding window-location as key prop to the element in route

ie

<Route path=":id" element={ <Hello key={window.location.pathname} } />

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 C NASIR
Solution 2 redapollos
Solution 3 FaFa
Solution 4
Solution 5 crispengari
Solution 6