router.query is empty in the first rendering
See original GitHub issueWhat version of Next.js are you using?
11.0.1
What version of Node.js are you using?
16.6.0
What browser are you using?
Chrome
What operating system are you using?
macOS
How are you deploying your application?
Nginx
Describe the Bug
Let’s say I have an order list page, it accept a optional parameter page
. I want use router.query
to get the parameter. The codes should be like this:
// pages/orders/index.js
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import { getOrderList } from "../api";
export default function Orders() {
const { query } = useRouter();
const [orders, setOrders] = useState([]);
useEffect(() => {
// I don't know if the query is really empty or because it is the first rendering.
const page = query.page || "1";
getOrderList(page).then(
(response) => {
setOrders(response);
},
() => {
// ...
}
);
}, [query]);
// ...
}
The problem is when I visit /orders?page=2
, the order list api will be requested twice. The first is to request the page 1, The second is to request the page 2. It because query
is a empty object in the first rendering, so when the effect first runs, the page is 1. And query
becomes { page: "2" }
after the first rendering by filling in the parameter, then it cause a top to down rerendering. The effect run again, and the page is 2 in this time.
And say I have another order detail page, it use dynamic route, I also want use router.query
to get the order id. The codes should be like this:
// pages/orders/[id].js
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import { getOrderDetail } from "../api";
export default function Orders() {
const { query } = useRouter();
const [order, setOrder] = useState([]);
useEffect(() => {
const id = query.id;
// I have to write this line because id is `undefined` when this effect first runs.
if (!id) return;
getOrderDetail(id).then(
(response) => {
setOrder(response);
},
() => {
// ...
}
);
}, [query]);
// ...
}
This is not ideal.
Expected Behavior
router.query
has parameters in the first rendering.
To Reproduce
See Describe the Bug.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
you can use
router.isReady
to check whether the query params have been updated client-side.This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.