loan
loan

Reputation: 75

router.query not updated after router.push in next/router

I have an issue I need to get query params after they are updated.

In this example when I make the console.log the router.query is reset to an empty object (and the route is been updated).

Why? What am I missing?

When I make router.push(/foo?page=1) it works!

Is it a bug ?

codesandbox link

import { useEffect } from "react";
import { useRouter } from "next/router";

export default function IndexPage() {
  const router = useRouter();

  useEffect(() => {
    console.log("router.query change", router.query);
  }, [router.query]);

  const changeRoute = () => {
    router.push("/foo", { query: { page: "1" } });
  };

  return (
    <div>
      <button onClick={changeRoute}> change route</button>
    </div>
  );
}

Upvotes: 5

Views: 7748

Answers (2)

juliomalves
juliomalves

Reputation: 50258

You're not using router.push correctly, the second argument where you're passing the query object is meant for the as parameter used to decorate the path.

If you want to use the URL object format to do the same as router.push("/foo?page=1"), then your code should look like the following.

router.push({
    pathname: "/foo",
    query: { page: "1" }
});

Upvotes: 10

Usman Sabuwala
Usman Sabuwala

Reputation: 900

I think in this case, it's better to use getServerSideProps. You can use the getServerSideProps function like this to catch the query params and then do whatever you want.

Also, I would recommend using the Link component from Next.js. It's a lot better and provides better accessibility than router.push.

import Link from 'next/link';

export const getServerSideProps = async context => {
  const page = context.query.page || 1;
  // Fetch new page or do whatever you want
  const data = await fetch(...);

  return {
    props: {
      page,
      data
    }
  }
}

export default function IndexPage({ page, data }) {
  return (
    <div>
      <Link href={{ pathname: '/foo', query: { page: '1' } }}>
        <a>
          <button>Change route</button>
        </a>
      </Link>
    </div>
  );
}

Upvotes: 1

Related Questions