TanStack / router

🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
https://tanstack.com/router
MIT License
8.11k stars 630 forks source link

useNavigate doesn't go to the new url #221

Closed chidimo closed 1 year ago

chidimo commented 2 years ago

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/react-location@3.5.0

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.
tannerlinsley commented 2 years ago

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

chidimo commented 2 years ago

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 react-location@3.1.11.

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 commented 2 years ago

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

I replaced imports of react-location@3.1.11 with @tanstack/react-location@3.5.0. 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>
  );
};
tannerlinsley commented 2 years ago

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

chidimo commented 2 years ago

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

aboutaaron commented 2 years ago

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!

cam31007 commented 2 years ago

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).

ccollie commented 2 years ago

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

tannerlinsley commented 2 years ago

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

JesusTheHun commented 2 years ago

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.

tom-ricci commented 2 years ago

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.

manqingchen commented 2 years ago

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

react-location@3.1.11@tanstack/react-location@3.5.0. 当我这样做时,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 commented 2 years ago

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

tom-ricci commented 2 years ago

@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.

Jared-Dahlke commented 2 years ago

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 commented 2 years ago

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

tannerlinsley commented 1 year ago

All should be fixed in the new "Router".

logicalahara commented 10 months ago

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='
    });