react-router (react-router-dom) v7 support
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";
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
@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'
In the code from my comment, it will coalesce to location coming from the useLocation hook.
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
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
is this still working as expected?
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
is this still working as expected?
Yes, like a charm 👍
For what it's worth, here's a TypeScript version that compiles:
// ReactRouter7Adapter.ts
import {useLocation, useNavigate} from 'react-router';
import type {
PartialLocation,
QueryParamAdapterComponent,
} from 'use-query-params';
export const ReactRouter7Adapter: QueryParamAdapterComponent = ({children}) => {
const navigate = useNavigate();
const location = useLocation();
return children({
location,
push: ({search, state}: PartialLocation) => navigate({search}, {state}),
replace: ({search, state}: PartialLocation) =>
navigate({search}, {replace: true, state}),
});
};