Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update path params when navigating to '.' #2415

Open
levrik opened this issue Sep 26, 2024 · 2 comments
Open

Cannot update path params when navigating to '.' #2415

levrik opened this issue Sep 26, 2024 · 2 comments

Comments

@levrik
Copy link
Contributor

levrik commented Sep 26, 2024

Which project does this relate to?

Router

Describe the bug

I wrote a hook which should replace the slug in the URL if it doesn't match reality anymore.
For example /projects/here-is-the-name-123 -> /projects/new-name-123.

navigate({ to: '.', params: { slug: 'new-name' }, replace: true });

Replacing search works without issues this way but not with params.

Your Example Website or App

https://stackblitz.com/edit/github-aitiwm?file=src%2Fmain.tsx

Steps to Reproduce the Bug or Issue

  1. Click on "Project 123" or "Document 123" link
  2. See old slug from path params rendered
  3. It should replace after 1 second but it does not

You can try replacing the to: '.' by a real route and see how it works but this then does not work for 2 different routes anymore.

Expected behavior

Path params to get replaced when navigating to '.'.

Screenshots or Videos

No response

Platform

  • OS: macOS
  • Browser: Edge
  • Version: 129

Additional context

No response

@Lokendra-sinh
Copy link

@levrik not sure what your end goal is but you can achieve the same functionality if you just pass the path in useFixUrl and use that path in the to: "path" option. Am not sure why . is not able to pick up the current route.

Code:

import React, { StrictMode, useEffect } from 'react';
import ReactDOM from 'react-dom/client';
import {
  Link,
  Outlet,
  RouterProvider,
  createRootRoute,
  createRoute,
  createRouter,
  useNavigate,
  useParams,
} from '@tanstack/react-router';
import { TanStackRouterDevtools } from '@tanstack/router-devtools';

const rootRoute = createRootRoute({
  component: () => (
    <>
      <div className="p-2 flex gap-2">
        <Link to="/" className="[&.active]:font-bold">
          Home
        </Link>{' '}
        <Link
          to="/projects/$slug"
          params={{ slug: 'old-name-123' }}
          className="[&.active]:font-bold"
        >
          Project 123
        </Link>{' '}
        <Link
          to="/projects/$slug/$documentId"
          params={{ slug: 'old-name-123', documentId: '123' }}
          className="[&.active]:font-bold"
        >
          Document 123
        </Link>
      </div>
      <hr />
      <Outlet />
      <TanStackRouterDevtools />
    </>
  ),
});

const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
  component: function Index() {
    return (
      <div className="p-2">
        <h3>Welcome Home!</h3>
      </div>
    );
  },
});

function useFixUrl(path: string) {
  const navigate = useNavigate();
  const slug = useParams({ strict: false, select: ({ slug }) => slug });

  useEffect(() => {
    if (slug !== 'new-name-123') {
      // Delayed for demonstration purposes
      setTimeout(() => {
        navigate({
          to: path,
          params: { slug: 'new-name-123' },
          replace: true,
        });
      }, 1000);
    }
  });

  return slug;
}

const projectsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/projects/$slug',
  component: function Project() {
    const slug = useFixUrl('/projects/$slug');

    return <div className="p-2">Hello from Projects {slug}!</div>;
  },
});

const documentsRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/projects/$slug/$documentId',
  component: function Project() {
    const slug = useFixUrl('/projects/$slug/$documentId');

    return <div className="p-2">Hello from Documents {slug}!</div>;
  },
});

const routeTree = rootRoute.addChildren([
  indexRoute,
  projectsRoute,
  documentsRoute,
]);

const router = createRouter({ routeTree, defaultPreload: 'intent' });

declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router;
  }
}

const rootElement = document.getElementById('app')!;
if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement);
  root.render(
    <StrictMode>
      <RouterProvider router={router} />
    </StrictMode>
  );
}

The "." being not able to pick up the current route is something we should definitely take a look at.

@levrik
Copy link
Contributor Author

levrik commented Sep 30, 2024

@Lokendra-sinh Yeah. That would probably work but is also more prone to errors when being copied around for example. Also route components cannot be nested (using Outlet) with it as otherwise calling the hook on parent route and child route would conflict. So getting "." fixed is still required for it to work in all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants