An alternative to useRouter
hook in next/router
that batches push
and replace
calls.
It allows for multiple push
without overwriting each other.
With next/router
, the code below doesn't work.
We expect query string to result in ?a=1&b=2
, but it results in ?a=1
or ?b=2
const router = useRouter();
const onClick = () => {
router.push({ query: { ...router.query, a: 1 } });
router.push({ query: { ...router.query, b: 2 } });
};
❌ Results in ?a=1
or ?b=2
By using useBatchRouter
, calls to push
are queued and merged together.
const batchRouter = useBatchRouter();
const onClick = () => {
batchRouter.push({ query: { a: 1 } });
batchRouter.push({ query: { b: 2 } });
};
✅ Results in ?a=1&b=2
$ yarn add next-batch-router
or
$ npm install next-batch-router
Set up <BatchRouterProvider/>
at the top of the component tree, preferably inside pages/_app.js
import { BatchRouterProvider } from "next-batch-router";
const MyApp = ({ Component, pageProps }) => (
<BatchRouterProvider>
<Component {...pageProps} />
</BatchRouterProvider>
);
Instead of using useRouter
from next/router
, use useBatchRouter
instead.
import { useBatchRouter } from "next-batch-router";
const Component = () => {
const batchRouter = useBatchRouter();
const onClick = () => {
batchRouter.push({ query: { a: 1 } });
batchRouter.push({ query: { b: 2 } });
};
return (
<div>
<button onClick={onClick}>Click me!</button>
</div>
);
};
batchRouter.push(url, as, options);
batchRouter.replace(url, as, options);
url
: { query?: SetQueryAction, hash?: string | null }
-
You cannot put
string
. Onlyobject
withquery
andhash
property is allowed. -
query
is similar to the originalquery
parameter with some differences.- Original
push
completely replaced the query string with the given object, butbatchRouter.push
merges the object by default. null
value removes the query parameter from the query string. CallingbatchRouter.push({query: {a: null}})
on?a=1&b=2
results in?b=2
.undefined
value is ignored. CallingbatchRouter.push({query: {a: undefined}})
on?a=1&b=2
results in?a=1&b=2
.- You can put a
function
instead of anobject
as aquery
parameter, similar toReact.useState
. However, the returned object is not merged automatically and must be merged manually within the function. Since merge is not automatically done, theundefined
value is handled asnull
and is removed from the query string.
- Original
-
hash
is the "hash" part from?param=foo#hash
url. It's similar to the originalhash
parameter with some differences.- Originally,
hash
was not preserved unless provided in therouter.push
call.batchRouter.push
preserves the original hash if not supplied. null
value removes the hash.- When multiple
push
calls have ahash
parameter, the last one is applied. - There is a bug in which removing all query parameters doesn't work if there is a hash in the URL. Such as this:
batchRouter.push({ query: ()=>({}), hash:"hash" })
- Originally,
as
?: { query?: SetQueryAction, hash?: string | null }
- Optional. Defines how the browser URL bar will look like. Can be used to set param in router.query but hide it from the URL. Check next/router documentation for more detail. Similar to
url
.
options
?: { scroll?: boolean, shallow?: boolean, locale?: string }
scroll
: Scroll to the top of the page after navigation. Defaults totrue
. When multiplepush
andreplace
calls are merged, all must havescroll: false
to not scroll after navigation.shallow
: Update the path of the current page without rerunninggetStaticProps
,getServerSideProps
orgetInitialProps
. Defaults tofalse
. When merged, all must haveshallow: true
to do shallow routing.locale
: Indicates locale of the new page. When merged, the last one will be applied.
useBatchRouter
is currently not designed to replace useRouter
. It's to be used together and useBatchRouter
should be used for changing only the query and hash part of the URL.
This project is licensed under the MIT License.