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

React-Router Location State being reset when changing queryState #839

Closed
Dentling opened this issue Jan 2, 2025 · 10 comments · Fixed by #840
Closed

React-Router Location State being reset when changing queryState #839

Dentling opened this issue Jan 2, 2025 · 10 comments · Fixed by #840
Labels
adapters/react-router Uses the React Router adapter bug Something isn't working released on @beta released

Comments

@Dentling
Copy link

Dentling commented Jan 2, 2025

Context

What's your version of nuqs?

    "nuqs": "2.3.0",

What framework are you using?

  • ✅ React Router

Which version of your framework are you using?

    "react-router": "6.22.3",
    "react-router-dom": "6.22.3",

Description

When using the state property of location to forward some state and then using the useQueryState function, the location.state is being reset to null.

I also already tried all the possible options in the useQueryState-Options like shallow: false and history: "push"

The location.state should not be deleted by changing the querystate in my opinion.

Reproduction

Component A:

   navigate(to, { state: { backTo: location } });

Component B:

  const location = useLocation();

  const [tab, setTab] = useQueryState('tab', {
    defaultValue: "home"
  });

  useEffect(() => {
    console.log(location.state);
  }, [location.state]);

When Component A navigates to Component B, the location.state is an Object containing the previous location.
When the Nuqs-QueryState is being updated, the location.state is being set to null.

@Dentling Dentling added the bug Something isn't working label Jan 2, 2025
@franky47 franky47 added the adapters/react-router Uses the React Router adapter label Jan 2, 2025
@franky47 franky47 added this to the 🪵 Backlog milestone Jan 2, 2025
@franky47
Copy link
Member

franky47 commented Jan 2, 2025

Thanks for the report, we do forward the history.state when doing shallow updates so I guess this location state lives somewhere else in the router memory, I'll have to dive into the React Router codebase to track it down.

Hopefully this is something that can be addressed without having to resort to a deep navigation (that calls the loaders).

@franky47
Copy link
Member

franky47 commented Jan 2, 2025

I managed to reproduce it, but only when using shallow: false. When not specifying that option (which is true by default), the state in location.state remains untouched on URL updates. Can you confirm this on your end?

@Dentling
Copy link
Author

Dentling commented Jan 2, 2025

Sadly I can not confirm.
I tried with the default shallow: true and with it being false but in both cases it set state to null.

In your Reproduction-setup have you also used it like in the root-component?

import { BrowserRouter } from 'react-router-dom';
import { NuqsAdapter } from 'nuqs/adapters/react-router';

<NuqsAdapter>
   <BrowserRouter>
      <App />
   </BrowserRouter>
</NuqsAdapter>

On Tab Change i directly call the updateFunction of the useOrderQuery and nothing else:

const [tab, setTab] = useQueryState('tab', {
  defaultValue: TabPanels.PICKING
});

const handleTabChange = useCallback(
  (_event: React.SyntheticEvent, value: TabPanels) => {
    setTab(value);
  },
  [setTab]
);

But I can see this in my console.log:

image

Have you also tested with ReactRouter: 6.22.3 ?

Or any other idea what could be the issue?

Thanks in advance.

@franky47
Copy link
Member

franky47 commented Jan 2, 2025

Could you try moving the adapter between BrowserRouter and the App components?

I'm surprised the adapter even works if not placed under BrowserRouter.

See #840.

@Dentling
Copy link
Author

Dentling commented Jan 2, 2025

That actually fixes it.
Thank you very much.

Although in the documentation under https://nuqs.47ng.com/docs/adapters#react-router-v6 it is specified to be the way I did it:

export function ReactRouter() {
  return (
    <NuqsAdapter>
      <RouterProvider router={router} />
    </NuqsAdapter>
  )
}

@franky47
Copy link
Member

franky47 commented Jan 2, 2025

Yeah that's what I just noticed when comparing with the e2e test environment.

There are so many ways to setup React Router, I might have to try them all to update the docs.

Regardless, the fix for shallow: false (which you only need if you have a loader that needs to read that search param) should be fairly easy.

@franky47
Copy link
Member

franky47 commented Jan 2, 2025

Could you please try the following (with shallow: false) and let me know if it keeps the location.state when updating the search params with nuqs?

pnpm add https://pkg.pr.new/nuqs@840

@Dentling
Copy link
Author

Dentling commented Jan 3, 2025

Yes I can verify.
With this PR the location.state does not get reset even when setting shallow: false.

Copy link

github-actions bot commented Jan 4, 2025

🎉 This issue has been resolved in version 2.3.1-beta.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Copy link

🎉 This issue has been resolved in version 2.3.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@franky47 franky47 removed this from the 🚀 Shipping next milestone Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
adapters/react-router Uses the React Router adapter bug Something isn't working released on @beta released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants