17

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

Ax0n
  • 436
  • 1
  • 4
  • 15
  • Please share how you are handling the ``clientId`` change. – programandoconro Aug 18 '21 at 02: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) – Ax0n Aug 18 '21 at 02:52

10 Answers10

14

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?

Enfield Li
  • 1,952
  • 1
  • 8
  • 23
  • 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. – Zombani Jul 23 '22 at 18:18
  • 1
    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 `` 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? – Alex Jun 24 '23 at 00:49
13

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! (:

Fredrik Meyer
  • 133
  • 2
  • 8
Panda
  • 154
  • 1
  • 2
3

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.

redapollos
  • 103
  • 8
  • 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. – Ax0n Dec 09 '21 at 07:23
2

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

C NASIR
  • 180
  • 3
  • 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`? – Ax0n Aug 18 '21 at 03:22
1

Maybe try the component Navigate:

<Navigate to={<your_path>}/>
FaFa
  • 358
  • 2
  • 16
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

akash
  • 11
  • 2
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

crispengari
  • 7,901
  • 7
  • 45
  • 53
  • 1
    Thanks Crispen, unfortunately v6 does not have the `useHistory()` hook. https://github.com/remix-run/react-router/issues/7476 - and even in the link you provided https://www.digitalocean.com/community/tutorials/react-react-router-v6#usenavigate-instead-of-usehistory – Ax0n Aug 18 '21 at 17:52
0

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

ie

<Route path=":id" element={ <Hello key={window.location.pathname} } />
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].

  • 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](/review/late-answers/32144395) – Francisco Maria Calisto Jul 06 '22 at 13:30
0

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

As of now I achieved using ../

navigate("../", {
      replace: true,
    });
Ebenezer
  • 1
  • 1
  • 3