server action being duplicated despite wrapping with react cache
Answered
netwrx posted this in #help-forum
netwrxOP
using 15.1.
it seems to only occur when using
can provide more code if needed. maybe im doing this wrong
-- i understand middleware exists but i prefer validation to be at the top level.
it seems to only occur when using
redirect
inside of a RSCcan provide more code if needed. maybe im doing this wrong
-- i understand middleware exists but i prefer validation to be at the top level.
Answered by Alfonsus Ardani
In any case, it looks like cache is doing its job correctly. It only shows once per request. The problem is (as near said), that the request is being made twice
47 Replies
i dont understand the context on how react's cache is being used here. Can you provide more information?
netwrxOP
yeah sure!
// actions.ts
const _get_session = async (): Promise<
Session | null
> => {
console.log("HIT at - ", new Date().toLocaleTimeString());
const store = await cookies();
const session_id = store.get("session");
if (!session_id) {
// cookie not found
return null;
}
const data = await db.stuff(session_id);
if (!data.length) {
return null;
}
return session;
};
export const get_session = cache(_get_session);
and, where are they used and what behavior did you expect them to do?
netwrxOP
everywhere kind of. im attempting to dedupe requests because i use the session's data on things like the layout, pages, components inside of those pages, etc.
in a single request?
netwrxOP
wdym?
you saw "HIT at - " console log being logged repeatedly in a single request?
netwrxOP
ah yes:
this is me simply going from / to /protected whilst logged in, using nextjs' Link component
// /protected/page.tsx
import { SignInForm } from "@/app/protected/components";
import { get_session } from "@/lib/server/auth/actions";
import Link from "next/link";
import { redirect } from "next/navigation";
export default async function Page() {
const session = await get_session();
if (session) {
redirect("/");
}
return (
<>
<Link href="/">go to /</Link>
{session ? <>ur already signed in dummy</> : <SignInForm />}
</>
);
}
✓ Starting...
✓ Ready in 1740ms
○ Compiling / ...
✓ Compiled / in 2.7s
HIT at - 11:10:32 PM
GET / 200 in 3279ms
✓ Compiled /favicon.ico in 206ms
GET /favicon.ico?favicon.45db1c09.ico 200 in 392ms
✓ Compiled /protected in 351ms
HIT at - 11:10:36 PM
GET /protected 200 in 641ms
HIT at - 11:10:37 PM
GET / 200 in 271ms
HIT at - 11:10:37 PM
GET / 200 in 271m
this is me simply going from / to /protected whilst logged in, using nextjs' Link component
netwrxOP
nope, that was the redirect's doings
why is redirect redirecting to
/
when already at /
?netwrxOP
because of the redirect in /protected
netwrxOP
no
do you have any idea why your app could've redirected to the same route from
/
to /
?netwrxOP
this is me simply going from / to /protected whilst logged in, using nextjs' Link component
i didnt press or do anything else 😭
in your protected page
delete
.next
folder and rerun npm devand see if
/
still gets logged twicenetwrxOP
same result...
Asian black bear
On a slightly different note, you're saying you are using a server action, but
_get_session
is not a server action. It's just a server-side function. And judging by your logs that Alfon pointed to caching is not the problem - just that you are requesting the root page twice for some reason. cache
only memoizes values during a single request.In any case, it looks like cache is doing its job correctly. It only shows once per request. The problem is (as near said), that the request is being made twice
Answer
netwrxOP
oh, never thought about in that perspective. i wonder if my browser is fucked
well, my initial suspect is the
prefetch
ing mechanism from Linkor your middleware
netwrxOP
dont have any middleware
dang
send your repo? maybe i can spot a mistake
netwrxOP
wow. it was absolutely my browser
wait how
netwrxOP
i spun up firefox
lmaooo wtf
✓ Starting...
✓ Ready in 1673ms
○ Compiling / ...
✓ Compiled / in 2.7s
HIT at - 11:20:35 PM
GET / 200 in 3151ms
✓ Compiled /protected in 345ms
HIT at - 11:20:37 PM
GET /protected 200 in 490m
this is absolutely what i expect wow
im slightly new to next.js in general. could you explain this difference please?
Asian black bear
A server action is a function that is explicitly marked using
"use server"
and callable from the client.netwrxOP
are there any gotchas between using a server sided function or action for my use case?
i know i could simply just create an api route to return the session for the client but
Asian black bear
It makes no sense to use dedicated server actions from server-side code if you meant that.
netwrxOP
ah, which i plan to do
Asian black bear
And since you seemingly want to check the session server-side while rendering the page you just use just regular functions.
No
"use server"
directives or any other magic.