router icon indicating copy to clipboard operation
router copied to clipboard

useNavigate doesn't go to the new url

Open chidimo opened this issue 3 years ago • 16 comments

Describe the bug When navigating with useNavigate() hook, the page doesn't load the new route unless I manually reload the browser window.

To Reproduce Inside any app using @tanstack/[email protected]

import {useNavigate} from '@tanstack/react-location';
const navigate = useNavigate();

// Any attempt to trigger navigate from a user action, 
// say a button click like below
navigate({to: '/new-route'})

// the URL in the browser changes
//  but the new location doesn't load.

chidimo avatar Feb 20 '22 02:02 chidimo

I’ll need you to replicate this in a code sandbox or online repl so I can debug it.

tannerlinsley avatar Feb 20 '22 10:02 tannerlinsley

So I have been trying to reproduce the issue I was facing in my app. It turns out I misdiagnosed the problem. My peculiar issue is that when I update my app URL with the useNavigate hook, the query params in another component are no longer reactive. It used to work when I was using [email protected].

I created a sandbox here to try to reproduce the problem but so far it works as expected but it doesn't work in my app.

I have to dig deeper and please let me know if I need to update this issue title or content and feel free to close it. I'll create a new one if, eventually, it turns out that I can reproduce a problem.

chidimo avatar Feb 20 '22 20:02 chidimo

So @tannerlinsley I think something is definitely amiss that I can't reproduce.

I replaced imports of [email protected] with @tanstack/[email protected]. When I do this the Link component changes the address in the address bar but the page doesn't change. The same thing happens when I update the search with the useNavigate hook.

I have been trudging through the documentation to see if the API changed in any significant way but I can't seem to find anything.

My setup looks like this

import {lazy, Suspense} from 'react';
import {Router, Route, ReactLocation, Outlet, MakeGenerics} from 'react-location';
import {parseSearch, stringifySearch} from 'react-location-jsurl';

type LocationGenerics = MakeGenerics<{
  Search: {...};
}>;

export const AppRoutes = (): JSX.Element => {
  const routes: Route<LocationGenerics>[] = [
    {
      path: '',
      element: <LazyLoadedComponent1 />,
   },
    {
      path: 'path2',
      element: <LazyLoadedComponent2 />,
   },

    {path: '*', element: <Error404 />},
  ];

  const reactLocation = new ReactLocation<LocationGenerics>({
    parseSearch,
    stringifySearch,
  });

  return (
    <Suspense fallback={<div>Suspended</div>}>
      <Router location={reactLocation} routes={routes}>
        <Outlet />
      </Router>
    </Suspense>
  );
};

chidimo avatar Feb 24 '22 10:02 chidimo

Are any of your router components perhaps using React.memo or using useMemo to memoize returned JSX?

tannerlinsley avatar Feb 24 '22 13:02 tannerlinsley

I can't find anywhere I memoized returned JSX in my code.

chidimo avatar Feb 24 '22 15:02 chidimo

I'm running into a similar issue where I'm getting Uncaught TypeError: Cannot read properties of undefined (reading 'search').

From what I can tell, navigate calls the .parseLocation method, which passes location.search to .parseSearch. (react-location/src/index.tsx#L462)

new ReactLocation() creates an instance of location under location.current, and it looks like the correct location.current value is passed to .parseSearch but I still receive an error.

I'll keep digging and see if I can find anything else. Thanks for this great library! It looks many of my problems with client-side routing so I hope I can get this to work!

aboutaaron avatar Mar 04 '22 18:03 aboutaaron

Hey all! I noticed a similar behavior while testing this package. I'm using create-react-app, I noticed whenever I update a file that contains a route loader and after fast-refresh is triggered, all the react-location links in the page would stop working (the URL would get updates, but the page content remains the same).

cam31007 avatar Mar 06 '22 20:03 cam31007

I'm having the same issue, but with a twist. It works with one search param, but not with a combination. For ex my-site/jobs?view=table would work, but my-site/jobs?view=table&page=1 would not trigger an update

ccollie avatar Apr 01 '22 01:04 ccollie

Very strange. As per usual, a CodeSandBox that exhibits the issue will help me fix this 100x faster and easier

tannerlinsley avatar Apr 01 '22 02:04 tannerlinsley

I have the same behavior, sometimes ! Sometimes it works just as expected, I close the browser, restart, and it doesn't work anymore. Sometimes in the opposite direction, broken => works.

JesusTheHun avatar May 04 '22 15:05 JesusTheHun

I seem to have similar behavior where all types of navigation sometimes don't work. I think its due to route caching since it seems to only happen when other routes change or I edit a data loader. I'll try to reproduce it in a sandbox.

tom-ricci avatar Jul 12 '22 07:07 tom-ricci

所以@tannerlinsley我认为肯定有一些我无法重现的问题。

[email protected]@tanstack/[email protected]. 当我这样做时,Link组件会更改地址栏中的地址,但页面不会更改。当我用useNavigate钩子更新搜索时,也会发生同样的事情。

我一直在翻阅文档以查看 API 是否有任何重大变化,但我似乎找不到任何东西。

我的设置看起来像这样

import {lazy, Suspense} from 'react';
import {Router, Route, ReactLocation, Outlet, MakeGenerics} from 'react-location';
import {parseSearch, stringifySearch} from 'react-location-jsurl';

type LocationGenerics = MakeGenerics<{
  Search: {...};
}>;

export const AppRoutes = (): JSX.Element => {
  const routes: Route<LocationGenerics>[] = [
    {
      path: '',
      element: <LazyLoadedComponent1 />,
   },
    {
      path: 'path2',
      element: <LazyLoadedComponent2 />,
   },

    {path: '*', element: <Error404 />},
  ];

  const reactLocation = new ReactLocation<LocationGenerics>({
    parseSearch,
    stringifySearch,
  });

  return (
    <Suspense fallback={<div>Suspended</div>}>
      <Router location={reactLocation} routes={routes}>
        <Outlet />
      </Router>
    </Suspense>
  );
};

I had this problem too, tried combining image

manqingchen avatar Jul 12 '22 08:07 manqingchen

I seem to have similar behavior where all types of navigation sometimes don't work. I think its due to route caching since it seems to only happen when other routes change or I edit a data loader. I'll try to reproduce it in a sandbox.

Try my method, please give me a reply if you can, thank you

https://github.com/TanStack/react-location/issues/221#issuecomment-1181480166

manqingchen avatar Jul 12 '22 08:07 manqingchen

@tannerlinsley I've played around with my own app a bit and noticed it's not necessarily caching that causes the router to break, but code changes. Any time the source code changes the router breaks. It's a bit much to put in a sandbox, so here's a working commit. Run npm run dev-install in /create-octobox-app, then run npm run dev in /app and mess around with any of the files in /app/src/windows. The config is generated from those files. Run npm run dev-uninstall in /create-octobox-app when you're done.

tom-ricci avatar Jul 26 '22 03:07 tom-ricci

I am having a similar issue

"react": "16.13.1",
"react-dom": "16.13.1",
"@tanstack/react-location": "^3.7.4",
const rlRoutes = [
        {
            path: 'one',
            element: (
                <div>
                    page 1 <Link to="/two">go to page 2</Link>
                </div>
            )
        },
        {
            path: 'two',
            element: (
                <div>
                    page 2 <Link to="/one">go to page 1</Link>
                </div>
            )
        }]

If I type the url in as /one , it works fine, now if i click "go to page 2" , the URL in the browser is updated to /two as expected, but the page still says "page 1"

Jared-Dahlke avatar Aug 16 '22 21:08 Jared-Dahlke

i just figured out it was not working because I had a useQuery in the same component that i had my <Router .../>

Jared-Dahlke avatar Aug 16 '22 21:08 Jared-Dahlke

All should be fixed in the new "Router".

tannerlinsley avatar Nov 10 '22 14:11 tannerlinsley

Are any of your router components perhaps using React.memo or using useMemo to memoize returned JSX?

@tannerlinsley Still facing rendering issue when route changes using useNavigate hook, returned component makes use of memo

export const AccountDetails: FC<AccountDetailsProps> = memo<AccountDetailsProps>(
  ({ userData, authConfig, allowSca }: AccountDetailsProps) => { ... });

logout navigation

await navigate({
      to: '/login/#/login?logout='
    });

logicalahara avatar Dec 19 '23 07:12 logicalahara