solid-router icon indicating copy to clipboard operation
solid-router copied to clipboard

Params don't change when changing URL

Open DasLixou opened this issue 3 years ago • 1 comments

Describe the bug

I have these routes in my Router with HashIntegration:

<Routes>
        <Route path="" component={Home} />
        <Route path="docs/:doc" component={Docs} />
</Routes>

Home just says home and Docs displays Doc: {and here the :doc from useParams().doc}

When i load the page at localhost:3000/#/ it works fine. Now when i change the url to localhost:3000/#/docs/cool and hit enter it also switches and shows Doc: cool. But when i change to url to localhost:3000/#/docs/notworkingsad it still shows Doc: cool and only when i hold shift and then refresh to rebuild the connection it shows Doc: notworkingsad.

so in short:

when using hashrouter and changing page, works fine. when then changing an parameter it doesnt reload the component with the parameter until i reload the whole page with a new connection.

Your Example Website or App

See code in Describe the bug section

Steps to Reproduce the Bug or Issue

See code in Describe the bug section

Expected behavior

Also "reload" the component with the new parameters like when switching the page.

Screenshots or Videos

No response

Platform

  • OS: [Windows]
  • Browser: I tested: [Chrome, Firefox]
  • Version: [OS, Browsers and all node packages are on the newest version]

Additional context

No response

DasLixou avatar Jul 15 '22 11:07 DasLixou

Are you listening to the parameter under a reactive context? The reason I ask is that we generally don't recreate the component in this scenario and instead update the reactive route parameters.

ryansolid avatar Jul 22 '22 17:07 ryansolid

hi @ryansolid , can you give us an example?

dnguyenfs avatar Sep 08 '22 02:09 dnguyenfs

Sure look at how params.id is accessed under the createResource. https://github.com/solidjs/solid-router#data-functions.

It might be easier to show me an example.

ryansolid avatar Sep 08 '22 02:09 ryansolid

{
    path: "/",
    component: () => {
      return (
        <Suspense fallback={<GlobalLoading fullscreen />}>
          <RootLayout />
        </Suspense>
      );
    },
    children: [
      {
        path: "/",
        component: () => {
          return (
            <Suspense fallback={<GlobalLoading fullscreen />}>
              <DefaultLocation />
            </Suspense>
          );
        },
      },
      {
        path: "/l/:lid",
        component: () => {
          return (
            <Suspense fallback={<GlobalLoading fullscreen />}>
              <MainLayout />
            </Suspense>
          );
        },
        children: [
          {
            path: "/",
            component: () => {
              return (
                <Suspense fallback={<GlobalLoading />}>
                  <Calendar />
                </Suspense>
              );
            },
          },
          {
            path: "/testing",
            component: () => {
              return (
                <Suspense fallback={<GlobalLoading fullscreen />}>
                  <Statistic />
                </Suspense>
              );
            },
          },
          {
            path: "/setting",
            component: () => {
              return (
                <Suspense fallback={<GlobalLoading />}>
                  <Setting />
                </Suspense>
              );
            },
            children: [
              {
                path: "/",
                component: () => {
                  return (
                    <Suspense fallback={<GlobalLoading />}>
                      <SettingDefault />
                    </Suspense>
                  );
                },
              },
              {
                path: "/staff",
                children: [
                  {
                    path: "/",
                    component: () => {
                      return (
                        <Suspense fallback={<GlobalLoading />}>
                          <SettingStaff />
                        </Suspense>
                      );
                    },
                  },
                  {
                    path: "/list",
                    component: () => {
                      return (
                        <Suspense fallback={<GlobalLoading />}>
                          <SettingStaffList />
                        </Suspense>
                      );
                    },
                  },
                ],
              },
              {
                path: "/something,
                component: () => {
                  return (
                    <Suspense fallback={<GlobalLoading />}>
                      <SOMETHING />
                    </Suspense>
                  );
                },
              },
            ],
          },
          {
            path: "/*all",
            component: lazy(() => import("./pages/notfound/Authenticated")),
          },
        ],
      },
    ],
  },

as you can see. when i navigate to http://localhost:3000/#/l/3 the lid params will be 3. after that i navigate to /l/4, the param lid not re-render. so when i click on nested route of that parent. it only navigate to prev lId.

in Main.ts Layout

const { lid } = useParams();
href={`/l/${lid}${item.path}`}

in Nested Setting Layout

const { lid } = useParams();
href={`/l/${lid}${item.path}/setting/staff`}
href={`/l/${lid}${item.path}/setting/something`}

dnguyenfs avatar Sep 08 '22 03:09 dnguyenfs

Yeah don't destructure from useParams

Try

const params = useParams();

href={`/l/${params.lid}${item.path}`}

The properties on the object are reactive so they need to be accessed under a tracking scope.

ryansolid avatar Sep 08 '22 03:09 ryansolid

Yeah don't destructure from useParams

Try

const params = useParams();

href={`/l/${params.lid}${item.path}`}

The properties on the object are reactive so they need to be accessed under a tracking scope.

oh my bad.... you save my day <3 , thank for quick response @ryansolid <3

dnguyenfs avatar Sep 08 '22 03:09 dnguyenfs

Had same issue. Below documentation is very useful:

https://github.com/solidjs/solid-router#useparams

const params = useParams();

// fetch user based on the id path parameter
const [user] = createResource(() => params.id, fetchUser);

The fetchUser won't be triggered if use params.id directly when createResource().

const params = useParams();

// Won't work!
const [user] = createResource(params.id, fetchUser);

tendant avatar Nov 28 '22 01:11 tendant