do something once server action is completed
Is there a way to achieve this (see title)? I’m using useTransition to start the action and need to close my modal once the action is completed successfully.
100 Replies
@ruhap I am using ispending, but how do I close the modal when I know isPending goes from true to false?
I might be drawing a blank if it’s obvious haha
how do you open it? using state? so change state
@ruhap yeah I know how to actually open and close it, it’s more of WHEN/WHERE do I close it?
I want it to auto close once the action has completed
And you have tried?
Are you using React Query?
Because if you are, this should be extremely trivial
I am not @deforestor
Just straight up server actions
So when it’s initially not pending (user hasn’t submitted form inside modal yet) won’t it close?
The form is inside the modal if that wasn’t clear my bad
why would it if you havent started transition
Right, that explains the confusion. I guess you could check for the status code, if it's 200, you set modal open to false on useEffect
But just so you know, adding React Query is no more than about 5 lines and would make everything else easy and also wouldn't break what you already have
console.log(isPending) and think from there
I’m assuming that’s gonna show
False (modal closed)
True (action happening)
False (action complete)
I’ll take a look tho, thx
I wasn’t sure if it would help with server actions yet but I’ll also consider adding it, thx
Ah, forget about it. I haven't checked the new server stuff yet, thought you were onto something else
Not sure if this is possible , need a callback that does not seem to exist.
Can you add a rough snippet of what your logic so far looks like? I get the idea, but there are many ways you could be instantiating the modal, for instance
@deathandtaxes Yeah sure!
So, I control if the modal is open/closed using an
isOpen
boolean state.
According to the NextJS docs, if a server action mutates data and calls redirect
, revalidatePath
, or revalidateTag
, you are supposed to use the useTransition
hook to start the action. (not sure why exactly)
This hook provides us with an isPending
boolean that represents if the action is running and a startTransition
function to start it.
The form inside of the modal should be disabled and show a spinner indicating when the server action is running. (I am ok with the UI being blocked here during this time).
My confusion is how to close the modal once the action is complete. I have it working as expected by just using it like an async function (see screenshot), but apparently its not the correct way. I am using react-hook-form and shadcn for my form validation so there is an onSubmit function I have available.seemingly working version but not correct way?
can you give the full component
Yep
That is the form
aight lemme cook
That is the modal
and createLink is a server action?
Yep
this might actually be pretty simple. See if it still works when you do
mmm wait
youll still need to pass the form params
Hmm I think I see what ur doing
Didn’t think of that
i think? try both
On why we use startTransition:
if you arent updating the client, you dont need to. Updating the client, as you outlined, includes doing any of
redirect, revalidatePath, or revalidateTag.
. If we ARE updating state, and therefore updating the client, this inherently means we are manipulating the client state in some way, since our UI is changing after the server action is complete. In react, we use startTransition
to start non-blocking state updates. So, in theory, if you use a server action & dont wrap it in startTransition
, your UI would completely block untill the server action is done. Since this is not what we want, we tell react to let the client continue to update and move around while the server is processing the request by wrapping it in the startTransition
.Ok that’s very clear, unless I missed it this would be extremely helpful in the official docs. I haven’t tried what you sent yet. Will do in a few min
do be warned, this is just me reverse engineering how next is working internally on the fly
so im not 100% sure this is exactly whats happening, but from what i can tell, looks right
From the research I’ve put together that all checks out as well
im actually gonna drop this in one of the main chats and see what everyone thinks
eh actually
im just gonna open a whole new question
@Josh also, this is the behavior I want (how it got it working in a hacky way)
https://cdn.discordapp.com/attachments/752647196419031042/1113205776501186631/Screen_Recording_2023-05-30_at_4.42.04_PM.mov
So I guess the UI is being blocked entirely, but it’s what I expect so idk
did the new approaches work?
On mobile atm, going to give it a try in a sec
kk
@Josh alright so neither working rn, getting a
This expression is not callable.
ah for when you pass e
thats fine, just remove the e
yeah thats with the e one
that actually makes sense
without e, I get
ah wait
i see
try this
err
there, try that
Ok no errors
what did u change
oh
since form.handleSubmit returns a function no need to wrap again
Let me give it a try
Ok we are getting immediate page reload
assuming because of preventdefault not happening
yep
yep
so
just do that part myself maybe?
alrightt I think thats working!
let me do a few more
Looks like its gooood
huuuuge
so huge, I have been stuck on this for a bit
much much appreciated
one more thing kinda unrelated
There is a layout shift when the revalidation is happening I believe, any idea on that? using next font
are you using tailwind
yea
lemme see your tailwind config and your app.tsx file
I assume you mean the root layout?
There are both
and your @/lib/fonts
Ah right
wait are you in app dir or pages
app dir
oh i se
i have my clerk provider outside the html
Oh I could probably do that, I think I saw it in the clerk docs like I have it but dont think it matters
the only thing i could imagine is removing the ...fontFamily.sans, i dont have that in my tailwind config and im also using those fonts
and i dont have artifacts when serveractions render
it could also be that on revalidation "Lone Link" is straight up gone
Yeah its quite odd I have no idea why thats happening
id have to inspect your actual repo to get an idea on that, however im guessing that 'Lone Link" is in a client compoent, and that text is expanding the box bigger than what its SSR height is
so when it refreshes, it re-executes the react, and then readjusts its size when it loads in
^ i just had this same issue, you can fix it pretty easily with max-height
just do
max-h-[whatever]
I have an explicit height on it rn actually
can you see your font flickering during load?
if not, then its not tailwind and it would be some CSS somewhere
nope only during that revalidation
hmm
also header is server comp
Oh wait "Lone Link" is a Next link
so that is probably a client comp if I had to guess
then its server iirc
(mine dont flicker)
No flickers on reloads, I will have to see what makes the revalidation any different
ah, i can confirm its your tailwind config
if you play back that video super slow, you can see the font changes
The last one I just sent?
the one i replied
Oh right
try using
damn same thing
I dont see it in this
video didnt catch it
hahaha
lol I swear it happened
its so quick
what is display swap?
not 100%, its in here tho
Optimizing: Fonts
Optimize your application's web fonts with the built-in
next/font
loaders.No idea what this means lol
same
hahahah
They use swap everywhere in docs
so I will roll with it
haha
Maybe I am using revalidate wrong
I passed "/dashboard" to it since thats the path of the page containing the data I need to refresh, thats good right?
i believe so
thats what i do
hmm and you dont get this with ur server actions?
nah mine run fine
hmm weird
🤷♂️
I can replicate it by toggling the font-mono variable
are you in a docker container by chance
Nope
hm
its something with tailwind
for sure
Yeah I agree, I’m gonna play around with how I’m setting the font up
Maybe the variable is not instantly ready or something