1

I'm upgrading react-router-dom from v5 to v6 in a codebase I'm not entirely familiar with yet, and I am curious about how to replace the following code:

const history = useHistory();
history.replace(url, params);

In the docs they only display what you would do to replace in case there's 1 argument. so if I had:

history.replace(url) 

I'd simply do:

const navigate = useNavigate();
navigate(url, {replace: true})

How do I ensure the second argument is kept with the useNavigate hook?

I'm tempted to do this:

const navigate = useNavigate();
navigate(url, params)

or

const navigate = useNavigate();
navigate(url, { state: params })

How should it be replaced without any impacts?

sergioviniciuss
  • 4,596
  • 3
  • 36
  • 50

1 Answers1

7

The state is sent in the second parameter under the state property, same as indicating a redirect (REPLACE) vs navigate (PUSH).

useNavigate

The useNavigate hook returns a navigate function:

declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
  (
    to: To,
    options?: { replace?: boolean; state?: any }
  ): void;
  (delta: number): void;
}

Note that the second argument is an options arg with replace and state properties.

Action v5
history = useHistory()
v6
navigate = useNavigate()
Navigate history.push(url) navigate(url)
Redirect history.replace(url) navigate(url, { replace: true })
Navigate w/state history.push(url, params) navigate(url, { state: params })
Redirect w/state history.replace(url, params) navigate(url, { replace: true, state: params })

navigate(url, params) would only work if params is an object with replace and/or state properties, e.g. { replace: true, state: { ... } }.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Maybe I wasn't clear enough, but the main thing in my case is that I'm not sure what to do with this second argument provided in my legacy code that was supported by the legacy history API. – sergioviniciuss Jun 02 '22 at 15:21
  • @sergioviniciuss I'm not sure what you mean by that then. What is the second argument in your legacy code? It looks like "state" you want to send in the route transition to me. – Drew Reese Jun 02 '22 at 15:24
  • 1
    Actually now that you updated the code I see it more clear, and I wasn't sure if it would be the state and how to combine it with replace. I'll give it a try and get back to you. This actually might be the trick! – sergioviniciuss Jun 02 '22 at 15:38
  • Btw, I have also another place where the first argument provided to replace is an object. history.replace({ search: params, hash }); I was expecting it to be a path. Do you also know how should it be replaced in V6? – sergioviniciuss Jun 02 '22 at 16:05
  • 1
    @sergioviniciuss In `react-router-dom@6` the `navigate` function takes a [`To`](https://github.com/remix-run/history/blob/main/docs/api-reference.md#to) argument that is either a partial `path` object or a path string. I think `navigate({ search: params, hash }, { replace: true });` should work. If you just need to update the queryString then there is also a [`useSearchParams`](https://reactrouter.com/docs/en/v6/hooks/use-search-params) hook that returns a function similar to `navigate` with regards to the `options` argument. – Drew Reese Jun 02 '22 at 16:11