28

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

2
  • Please share how you are handling the clientId change. Commented Aug 18, 2021 at 2:47
  • @programandoconro - does that help? i can verify that the console.log(clientId) part is logging the desired information (the clientId I want to navigate to) Commented Aug 18, 2021 at 2:52

11 Answers 11

27

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 /same_path/foo to /same_path/bar.

Be aware of unintended page referesh behavior:

For a normal situation like navigate from /home to /same_path/bar, navigate(0) will cause page to refresh even after page has finished rendering. And to prevent that, you can take a look at this question.

More info:

  1. useNavigate docs

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

Sign up to request clarification or add additional context in comments.

3 Comments

Hello, I've tried and it worked, but because of reloading 2 times, when I click back on Browser, it's kind of weird like first back it ok, but the second back it shows the same page.
This workaround works for me and is great but I'm curious why we need to manually refresh with navigate(0)? Seems a little hacky and navigate('url') should work out of the box. FWIW I am unable to get the wrapper <Navigate> to work as well and I'm suspecting this is the reason. Perhaps there's a root cause specific to our applications that should be fixed?
In my case I was just going one step back, URL would change but the UI(view) stayed same or say used to become more messed up, I had to load the URL manually using window.location, using navigate(0) is a better work around for me, as I don't have to worry about loading the URL, which will change for Dev and Prod. Thanks Still have to find a solution for this!
22

I just read in React Router Dom Docs v6 this solution:

import { useNavigate } from 'react-router-dom';
...
const navigate = useNavigate();
...
<Button onClick={() => navigate('../user', { replace: true })}>Register</Button>

So, basically I added ../ before the route and the replace: true.
Reference: https://reactrouter.com/en/6.9.0/hooks/use-navigate

It worked for me, hope it works for u! (:

Comments

4

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.

1 Comment

Good suggestion @redapollos - thank you. the issues link gave me an idea - I will post my learning here as soon as I can try it out.
3

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

1 Comment

Thanks @C, unfortunately this does not have any effect. I think it makes sense that we wouldn't want to replace the current .../foo location in the history stack either way though. what if we wanted to navigate back to foo from bar?
1

Maybe try the component Navigate:

<Navigate to={<your_path>}/>

Comments

1

This might be a little late but I had the same issue and you simply just have to trigger a re-render for your component. You can do this by adding a useEffect hook within your component you have assigned /dashboard/clients/:clientId to with a dependency of the param you want to update.

It should look something like this:

import React, { useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom';


const ClientDashboard = () => {

    const params = useParams()
    const navigate = useNavigate()

    useEffect(() => {
    //do something with new id 
    },[params.clientId])

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

    .....
}

Your page should now update with the new param

Comments

1

I'm using react-router-dom@^6.6.2

As of now I achieved using ../

navigate("../", {
      replace: true,
    });

Comments

1

replace: true will remove the users ability to navigate back in history which Im guessing you might not want, if you just want to replace the entire path try:

navigate('../newpath')

this will remove the entire route using the .. and replace it with your new one.

Comments

0

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

1 Comment

Thanks Crispen, unfortunately v6 does not have the useHistory() hook. github.com/remix-run/react-router/issues/7476 - and even in the link you provided digitalocean.com/community/tutorials/…
0

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

ie

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

1 Comment

There was the same issue with v5 also . So, check. it might work. if you already solved it could you explain it too?
0

Based on this link https://github.com/remix-run/react-router/issues/8245 I could solve this issue.

I guess that as nothing has been changed the screen is not updated. As soon as I added I useEffect on the target route component and passed the lastelement as a parameter it worked.

In other words: On the target component add: Reac.useEffect(....) [lastElement].

1 Comment

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.