admin管理员组文章数量:1288075
I'm working on a Next.js application where I'm creating a new payment record in the database. After the record is created, I want to refresh the page to display the updated list of payments. I'm using router.refresh()
, but the new data isn't showing up unless I manually refresh the entire browser.
I have a page app/(user)/user/[userId]/page.tsx
which is set to be dynamically rendered.
import { Suspense } from "react";
import { UserIdPageWrapper } from "./_components/userId-page-wrapper";
interface UserIdPageProps {
params: Promise<{ userId: string }>;
}
export const dynamic = "force-dynamic";
export default async function UserIdPage({ params }: UserIdPageProps) {
const { userId } = await params;
return (
<Suspense fallback={<div>Loading...</div>}>
<UserIdPageWrapper userId={userId} />
</Suspense>
);
}
The page uses a component called UserIdPageWrapper
to fetch the user and payment data:
import { db } from "@/lib/db";
import { UserInfo } from "./userInfo";
import { redirect } from "next/navigation";
interface UserIdPageWrapperProps {
userId: string;
}
export const UserIdPageWrapper = async ({ userId }: UserIdPageWrapperProps) => {
const [userData, paymentsData] = await Promise.all([
db.user.findUnique({
where: {
id: userId,
},
}),
db.payment.findMany({
where: {
userId: userId,
},
include: {
items: true,
},
}),
]);
if (!userData || !paymentsData) {
redirect("/");
}
return (
<UserInfo
user={userData}
payments={paymentsData}
/>
);
};
Inside the UserInfo
component (a client component), I have a function handleAddPayment
that sends a POST request to create a new payment:
"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
interface userInfoProps {
user: User;
payments: (Payment & { items: PaymentItem[] })[];
}
export const UserInfo = ({ user, payments }: userInfoProps) => {
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const handleAddPayment = async () => {
setIsLoading(true);
try {
const res = await fetch("/api/payments", {
method: "POST",
body: JSON.stringify({
userId: user.id,
totalAmount: 0,
supervisionRatio: 0,
}),
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
throw new Error("Failed to add payment");
}
const jsonData = await res.json();
console.log(jsonData);
toast.success("New payment added");
router.refresh();
} catch (error) {
toast.error("Failed to add payment");
} finally {
setIsLoading(false);
}
};
// ... rest of the component
};
The /api/payments
route handler looks like this:
import { NextResponse } from "next/server";
import { db } from "@/lib/db";
export async function POST(req: Request) {
try {
const { userId, totalAmount, supervisionRatio } = await req.json();
const res = await db.payment.create({
data: {
userId,
totalAmount,
supervisionRatio,
supervisionFee: (totalAmount * supervisionRatio) / 100,
paymentDate: new Date(),
remainingAmount: totalAmount - (totalAmount * supervisionRatio) / 100,
},
});
return NextResponse.json(res);
} catch (error) {
console.error("[ORDERS_POST]", error);
return new NextResponse("Internal error", { status: 500 });
}
}
I've tried setting export const dynamic = "force-dynamic";
in my page.tsx
file, but it's still not working.
What I've tried:
- Using
router.refresh()
after the POST request. - Setting
dynamic = "force-dynamic"
in thepage.tsx
file.
What I expect:
After creating a new payment, I expect the PaymentList
component to re-render with the updated list of payments without a full browser refresh.
Question:
What am I missing? Is there a caching issue, or is router.refresh()
not the correct approach for this scenario? How can I ensure that the page updates with the new data after the POST request?
I'm working on a Next.js application where I'm creating a new payment record in the database. After the record is created, I want to refresh the page to display the updated list of payments. I'm using router.refresh()
, but the new data isn't showing up unless I manually refresh the entire browser.
I have a page app/(user)/user/[userId]/page.tsx
which is set to be dynamically rendered.
import { Suspense } from "react";
import { UserIdPageWrapper } from "./_components/userId-page-wrapper";
interface UserIdPageProps {
params: Promise<{ userId: string }>;
}
export const dynamic = "force-dynamic";
export default async function UserIdPage({ params }: UserIdPageProps) {
const { userId } = await params;
return (
<Suspense fallback={<div>Loading...</div>}>
<UserIdPageWrapper userId={userId} />
</Suspense>
);
}
The page uses a component called UserIdPageWrapper
to fetch the user and payment data:
import { db } from "@/lib/db";
import { UserInfo } from "./userInfo";
import { redirect } from "next/navigation";
interface UserIdPageWrapperProps {
userId: string;
}
export const UserIdPageWrapper = async ({ userId }: UserIdPageWrapperProps) => {
const [userData, paymentsData] = await Promise.all([
db.user.findUnique({
where: {
id: userId,
},
}),
db.payment.findMany({
where: {
userId: userId,
},
include: {
items: true,
},
}),
]);
if (!userData || !paymentsData) {
redirect("/");
}
return (
<UserInfo
user={userData}
payments={paymentsData}
/>
);
};
Inside the UserInfo
component (a client component), I have a function handleAddPayment
that sends a POST request to create a new payment:
"use client";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-hot-toast";
interface userInfoProps {
user: User;
payments: (Payment & { items: PaymentItem[] })[];
}
export const UserInfo = ({ user, payments }: userInfoProps) => {
const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const handleAddPayment = async () => {
setIsLoading(true);
try {
const res = await fetch("/api/payments", {
method: "POST",
body: JSON.stringify({
userId: user.id,
totalAmount: 0,
supervisionRatio: 0,
}),
headers: {
"Content-Type": "application/json",
},
});
if (!res.ok) {
throw new Error("Failed to add payment");
}
const jsonData = await res.json();
console.log(jsonData);
toast.success("New payment added");
router.refresh();
} catch (error) {
toast.error("Failed to add payment");
} finally {
setIsLoading(false);
}
};
// ... rest of the component
};
The /api/payments
route handler looks like this:
import { NextResponse } from "next/server";
import { db } from "@/lib/db";
export async function POST(req: Request) {
try {
const { userId, totalAmount, supervisionRatio } = await req.json();
const res = await db.payment.create({
data: {
userId,
totalAmount,
supervisionRatio,
supervisionFee: (totalAmount * supervisionRatio) / 100,
paymentDate: new Date(),
remainingAmount: totalAmount - (totalAmount * supervisionRatio) / 100,
},
});
return NextResponse.json(res);
} catch (error) {
console.error("[ORDERS_POST]", error);
return new NextResponse("Internal error", { status: 500 });
}
}
I've tried setting export const dynamic = "force-dynamic";
in my page.tsx
file, but it's still not working.
What I've tried:
- Using
router.refresh()
after the POST request. - Setting
dynamic = "force-dynamic"
in thepage.tsx
file.
What I expect:
After creating a new payment, I expect the PaymentList
component to re-render with the updated list of payments without a full browser refresh.
Question:
What am I missing? Is there a caching issue, or is router.refresh()
not the correct approach for this scenario? How can I ensure that the page updates with the new data after the POST request?
1 Answer
Reset to default 0Since you're using NextJS with app router, you should be using revalidatePath
instead of a call to router.refresh
. Typically, when you perform an update in a server action or route handler, you'll need to call the revalidatePath
from next-cache
in order to refresh the data in the cache and to have access to the updated data.
import { revalidatePath } from "next/cache";
export async function POST(req: Request) {
try {
const { userId, totalAmount, supervisionRatio } = await req.json();
const res = await db.payment.create({
data: {
userId,
totalAmount,
supervisionRatio,
supervisionFee: (totalAmount * supervisionRatio) / 100,
paymentDate: new Date(),
remainingAmount: totalAmount - (totalAmount * supervisionRatio) / 100,
},
});
revalidatePath("/posts") //This assumes /post is the path being revalidated.
return NextResponse.json(res);
} catch (error) {
console.error("[ORDERS_POST]", error);
return new NextResponse("Internal error", { status: 500 });
}
}
本文标签: javascriptNextjs routerrefresh() not updating data after POST requestStack Overflow
版权声明:本文标题:javascript - Next.js `router.refresh()` not updating data after POST request - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741335980a2373042.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论