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 (react-router-dom) v7 support #295

Open
shadoworion opened this issue Nov 26, 2024 · 4 comments
Open

react-router (react-router-dom) v7 support #295

shadoworion opened this issue Nov 26, 2024 · 4 comments

Comments

@shadoworion
Copy link

Error when moving from "react-router-dom" to "react-router"

✘ [ERROR] Could not resolve "react-router-dom"

    node_modules/use-query-params/adapters/react-router-6/index.js:7:7:
      7 │ } from "react-router-dom";
@KevinKingsbury
Copy link

You can make your own adapter and use that instead of the ReactRouter6Adapter in your QueryParamProvider. I just took the one from here and changed the import.

import { useContext } from 'react';
import {
  UNSAFE_NavigationContext,
  useNavigate,
  useLocation,
  UNSAFE_DataRouterContext,
} from 'react-router'; // changed from react-router-dom

const ReactRouter7Adapter = ({ children }) => {
  // we need the navigator directly so we can access the current version
  // of location in case of multiple updates within a render (e.g. #233)
  // but we will limit our usage of it and have a backup to just use
  // useLocation() output in case of some kind of breaking change we miss.
  // see: https://github.com/remix-run/react-router/blob/f3d87dcc91fbd6fd646064b88b4be52c15114603/packages/react-router-dom/index.tsx#L113-L131
  const { navigator } = useContext(UNSAFE_NavigationContext);
  const navigate = useNavigate();
  const router = useContext(UNSAFE_DataRouterContext)?.router;
  const location = useLocation();

  const adapter = {
    replace(location) {
      navigate(location.search || '?', {
        replace: true,
        state: location.state,
      });
    },
    push(location) {
      navigate(location.search || '?', {
        replace: false,
        state: location.state,
      });
    },
    get location() {
      // be a bit defensive here in case of an unexpected breaking change in React Router
      return router?.state?.location ?? navigator?.location ?? location;
    },
  };

  return children(adapter);
};

Put that in your project somewhere and import it instead of use-query-params/adapters/react-router-6

@shadoworion
Copy link
Author

@KevinKingsbury

Yea, It's working.

Only one thing...
I don't know, is it important?

const { navigator } = useContext(UNSAFE_NavigationContext);
...
navigator?.location -> /// Property 'location' does not exist on type 'Navigator'

@KevinKingsbury
Copy link

In the code from my comment, it will coalesce to location coming from the useLocation hook.

@ddolcimascolo
Copy link

Hi all,

I've had success with an adapter as simple as:

import { useLocation, useNavigate } from 'react-router';

export default function ReactRouterAdapter({ children }) {
  const navigate = useNavigate();

  return children({
    location: useLocation(),
    push: location => navigate({ search: location.search }, { state: location.state }),
    replace: location => navigate({ search: location.search }, { replace: true, state: location.state })
  });
}

Without using all the RR internals. My test suite is all green and the app works as expected. Not sure why this was required in the first place...

Cheers,
David

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

3 participants