In my React application, I do multiple updates of the URI (I add query parameters) within the same event with Next router.push
. The issue is that some updates are lost because updates are not based on the previous state.
Here is a minimal working example to illustrate the issue:
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function IndexPage() {
const router = useRouter();
useEffect(() => {
router.push({
pathname: router.pathname,
query: { ...router.query, x: 'foo' },
});
router.push({
pathname: router.pathname,
query: { ...router.query, y: 'bar' },
});
router.push({
pathname: router.pathname,
query: { ...router.query, z: 'baz' },
});
}, [router.pathname, router.query.x, router.query.y, router.query.z]);
return (
<ul>
{Object.entries(router.query).map((entry) => (
<li>
{entry[0]}: {entry[1]}
</li>
))}
</ul>
);
}
It renders
- x: foo
- z: baz
instead of
- x: foo
- y: bar
- z: baz
If router.push
accepted updater functions like the set
function returned by useState
, it would solve the issue elegantly:
router.push(prevUrl => {
pathname: prevUrl.pathname,
query: { ...prevUrl.query, x: 'foo' },
});
router.push(prevUrl => {
pathname: prevUrl.pathname,
query: { ...prevUrl.query, y: 'bar' },
});
router.push(prevUrl => {
pathname: prevUrl.pathname,
query: { ...prevUrl.query, z: 'baz' },
});
Is there an alternative solution?