pbeshai / use-query-params

React Hook for managing state in URL query parameters with easy serialization.
https://pbeshai.github.io/use-query-params
ISC License
2.17k stars 96 forks source link

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

Open shadoworion opened 6 days ago

shadoworion commented 6 days ago

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 commented 4 days ago

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 commented 6 hours ago

@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 commented 1 hour ago

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