remix-run / react-router

Declarative routing for React

Home Page:https://reactrouter.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug]: `window.location` is not updated after a call to `router.navigate()`

scallaway-uipath opened this issue · comments

What version of React Router are you using?

^6.23.0

Steps to Reproduce

When using React Router in a test suite, I'm observing that window.location does not get updated when a call to router.navigate() is made.


I'm trying to test a custom hook who's return value is dependent on the current state of the URL. For performance purposes, we're getting the current location of the app from window.location, rather than through useLocation() (we have a separate, but similar, hook that calls this).

The setup in the tests is the following:

  • Latest version of React Router
  • Testing with React Testing Library, powered by vitest
  • router is the result of calling createMemoryRouter() with an array of RouteObject's, which is then given to the <RouterProvider /> in the wrapper key of rendeHook() accordingly.
  • I've specified initialProps for the hook that I'm testing
  • I'm updating the URL through the use of router.navigate(), called inside an act() statement

What I'm seeing, at the point when I call rerender() after router.navigate() has updated the URL, is that the value of useLocation().pathname is not equal to the value of window.location.pathname. useLocation() is set to the value that router.navigate() just defined, but window.location is being left behind.


For what it's worth, this seems to be the opposite of #11473

Expected Behavior

window.location.pathname === useLocation().pathname after router.navigate() is called

Actual Behavior

window.location is still set to the previous location whereas useLocation is updated correctly

You're using createMemoryRouter which doesn't interact with window at all. If you need to test window you will need to use createBrowserRouter in your tests - and generally want to pass it the window instance you are using in your test setup.

However, if you're not testing specific DOM stuff I would recommend using createMemoryRouter and asserting against router.state.location in your tests for simplicity.