My Problem with Next.js Server Actions

แชร์
ฝัง
  • เผยแพร่เมื่อ 14 ต.ค. 2024
  • I spent hours trying to get loading states to work with Server Actions. Here's what I learned about how to fix it along with a few other tips and gotchas.
    Server Actions - nextjs.org/doc...
    Thanks to Xata and Sentry for sponsoring my time to work on Deals for Devs!
    Try Xata - xata.io/
    Try Sentry - sentry.io/
    *Newsletter*
    Newsletter 🗞 - www.jamesqquic...
    *DISCORD*
    Join the Learn Build Teach Discord Server 💬 - / discord
    Follow me on Twitter 🐦 - / jamesqquick
    Check out the Podcast - compressed.fm/
    Courses - jamesqquick.co...
    *QUESTIONS ABOUT MY SETUP*
    Check out my Uses page for my VS Code setup, what recording equipment I use, etc. www.jamesqquic...

ความคิดเห็น • 51

  • @elramtv
    @elramtv 10 หลายเดือนก่อน +26

    "I pushed this code to production without testing..."
    now starts the fun part.

  • @masonsten
    @masonsten 10 หลายเดือนก่อน +17

    I think it makes more sense if you think of the form as a context provider. The useFormStatus can't be used above the context of the form, and as others have mentioned what if you had multiple forms on one page? Also its honestly a better way to to code it anyways since your form stays mostly server side and and your submit button can now be reused in any form component and it'll just work. Definitely a bit annoying though if you don't know the rules. Gonna need some eslint rules to help with things like this I think

  • @francismori7
    @francismori7 10 หลายเดือนก่อน +34

    To be fair, your pending variable from useFormStatus would have no way to know which form to target if there were 3 different forms in your component

    • @ukeshrestha
      @ukeshrestha 10 หลายเดือนก่อน +5

      You have to use form prop in button and add id of the form as value so that button knows which form it belongs to

  • @aritrasadhukhan5674
    @aritrasadhukhan5674 28 วันที่ผ่านมา

    Was scratching my head on for the last two hours, finally with this video was able to make it work

  • @nickculpin
    @nickculpin 10 หลายเดือนก่อน +7

    you can put that actions file inside your app directory using the app router, it doesn't need to be in the root. I ended up using a dedicated actions file per view, which created a "model view controller" like structure.

  • @StephenRayner
    @StephenRayner 4 หลายเดือนก่อน

    I like the final solution, I feel it makes sense.
    1. Not forcing the form to be a client component.
    2. The button owns the pending state
    Curious how this will work if you have two forms visible at once. Will need to try that out to see if it puts both or just 1 into the pending state.

  • @metalbroga
    @metalbroga 10 หลายเดือนก่อน +1

    I went through that same issue few weeks ago. its really a weird design decision and as you said they probably have a reason for this. it is what it is, but this is when I always have the impression that Remix do things better.

    • @patrickjreid
      @patrickjreid 10 หลายเดือนก่อน

      I agree completely. I wish my company hadn't gone with Next. But I was too new to make the big design decision. When I am the lead at a startup I am going to go with Remix.

  • @mathiasriissorensen6994
    @mathiasriissorensen6994 10 หลายเดือนก่อน

    It's exactly what I have been struggling with the past couple of days! Except that I'm trying to upload a new avatar with a preview, which complicated things a bit. But thank you for this video!

  • @ZadSoleimaninia
    @ZadSoleimaninia 8 หลายเดือนก่อน

    James you are awesome!
    @7:35 - Basically any that uses hooks must be converted into a client component or else it won't work!
    I think what's happening behind the scenes is the server component that contains the form body must be checked every second or something as ping-pong and it keeps feeding this status back to the hook form in the client side! and most likely this must be a child component because if it was all at same level , because the ui button needs to change visually it therefore requires a DOM render and this can't happen as server level!
    Hopefully it makes sense :)
    I worked on something similar and had to ask a another engineer where he explained this in this way!
    Thanks for the video :)

  • @ukeshrestha
    @ukeshrestha 10 หลายเดือนก่อน +1

    You have to use form prop on button and add id of the form as value so that button knows which form it belongs to

  • @rafi-hidayat
    @rafi-hidayat 10 หลายเดือนก่อน +1

    almost the same issue, but i choose to use zustand where it has "loading and action key" so each action has its own pending/loading state

  • @codeSTACKr
    @codeSTACKr 10 หลายเดือนก่อน

    very interesting the way this has to be set up 🤔

  • @ronaldpaek
    @ronaldpaek 10 หลายเดือนก่อน

    Hey James when did you make this course React and Serverless on your website? I know the Astro one is your newest course. :)

  • @bradgarropy
    @bradgarropy 10 หลายเดือนก่อน +4

    Dude, I'm telling you, Remix is Next.js without all these little frustrations!

  • @noeldolan518
    @noeldolan518 10 หลายเดือนก่อน

    Great video! :). For form validation @ 9:04, I think you can use z.object({name:... }).strict() to ensure the submit form match your database table schema.

  • @StephenRayner
    @StephenRayner 4 หลายเดือนก่อน

    High quality! 🎉🎉🎉

  • @RationalDissonances
    @RationalDissonances 10 หลายเดือนก่อน

    how to let my component know that form submission was successful or got rejected? basically how can I return data from my server actions?

    • @jmagrippis
      @jmagrippis 10 หลายเดือนก่อน

      It’s the ‘useFormState’ hook. Your server action can then return anything, and it will be made available to the UI.
      I find that if I’ve set things up correctly and the form succeeds, I don’t need to return anything (since the form redirects, or invalidates data that gets re fetched, and everything just works), so I just return an object with an ‘error’, that describes what went wrong, when something failed. Just make sure to return ‘{ error: “” }’ when the form succeeds!
      (Or a message or error code, when server-side form validation failed, or a legit 500 error where my code had a problem)

  • @jeromealtariba7339
    @jeromealtariba7339 9 หลายเดือนก่อน

    When using actions, react hook forms and Zod as validator, the schema validation at submission is not triggered when the mode is "onSubmit" (default). The submission to the action is done, even if the data are not schema compliant. The validation works when setting the mode to "onBlur", "onChange". Any Idea what is wrong?

  • @arslanali774
    @arslanali774 4 หลายเดือนก่อน

    How you'd expect the hook to work and know which form to target obviously the button has to be a component.

    • @JamesQQuick
      @JamesQQuick  3 หลายเดือนก่อน +1

      The button would be inside of the form...it doesn't seem that hard honestly lol I think has since been fixed so it couldn't have been that hard.

  • @colinclark7854
    @colinclark7854 8 หลายเดือนก่อน

    The problem this approach surfaces, though, is that the useFormState hook now cannot be used in the form component, as it is now not a client component. Handling the validation in your UI will now be more problematic

  • @petecapecod
    @petecapecod 10 หลายเดือนก่อน

    I think we should ALL just dump any errors in the console and let the user figure it out 🤣
    Great video, totally a mistake I would make 💯
    Refractor the button 🤦🏻‍♂️

  • @justine_chang39
    @justine_chang39 10 หลายเดือนก่อน +4

    thank you for giving me another reason why I'm not gonna use Server Actions

  • @NickEngelhardt
    @NickEngelhardt 8 หลายเดือนก่อน

    I have a form where I have "formsteps" (with values for type, name, placeholder etc) mapped out into inputs with dynamic values. This does not appear to work with the whole server action and FormData thing. If I just have a regular input that isnt mapped out, it works just fine. Has anyone encountered and solved this problem?

  • @yassinesafraoui
    @yassinesafraoui 10 หลายเดือนก่อน

    I don't know why I feel weird about adding the thank you page, it feels like anyone can access that button without having submitted a deal, I actually ran into a pretty similar situation, I know it's not a big deal, it's just feel like in a perfect world something like the deal id should be passed to the thank you route so that it only accepts created deals, but I don't get to think of a good way to do it, maybe query params idk

  • @tr.j4079
    @tr.j4079 9 หลายเดือนก่อน +1

    You said it’s “exactly” what you did but it’s obviously not haha since the example was a self-contained button component with a loading state while yours was a giant component with the form and loading outside of the form. 😢

    • @tr.j4079
      @tr.j4079 9 หลายเดือนก่อน +1

      It has to be this way because the hook is running on client side. But the button is already in the server boundary since you placed it in the form. So what happens now is that when you click the button, it will not be able to use the hook that’s outside of its server boundary. They probably can do a better job in helping devs visualise these boundaries though.

  • @hongz1
    @hongz1 6 หลายเดือนก่อน

    Easiest way is to use react-form-hook with server action.

  • @vinaciotm
    @vinaciotm หลายเดือนก่อน

    i prefer useActionState
    const [state, action, pending] = useActionState(someServerActionFn, { some : 'state' })

  • @haroldpepete
    @haroldpepete 7 หลายเดือนก่อน

    this video looks more like a someone advertising a product than a nextjs related video, take your thumb down with all my force, you deserve it more than anybody

  • @jonathangamble
    @jonathangamble 10 หลายเดือนก่อน +1

    I did the same thing lol

  • @mDHARYL
    @mDHARYL 5 หลายเดือนก่อน

    its just a little bit of misunderstanding :D

  • @Tyler-pz2ol
    @Tyler-pz2ol 8 หลายเดือนก่อน

    Seriously feels like React is taking a step backwards. Things are once again becoming way too overly complex - at least in my opinion.

  • @StephenRayner
    @StephenRayner 4 หลายเดือนก่อน

    Eww... `return console.error(error)` console.error doesn't return anything

  • @drdDavi
    @drdDavi 10 หลายเดือนก่อน +1

    No no no. Why do we need to jump through so many hurdles. This ruins productivity!!! Just use the pages router, be productive!

    • @taunado
      @taunado 10 หลายเดือนก่อน

      pages router and getserversideprops?

    • @trace6585
      @trace6585 10 หลายเดือนก่อน

      pages router sucks and the reason people don't switch to app is because they are too lazy to learn new things

  • @googoochu3923
    @googoochu3923 3 หลายเดือนก่อน

    Skill issue

    • @JamesQQuick
      @JamesQQuick  3 หลายเดือนก่อน

      aha thanks!

  • @iwanttopunchtheosface
    @iwanttopunchtheosface 10 หลายเดือนก่อน

    Router 6.4 loader and action saved me from a lot of headache and Nextjs implementation just doesn't feel right. Remix is the way.

  • @jeromealtariba7339
    @jeromealtariba7339 9 หลายเดือนก่อน

    When using actions, react hook forms and Zod as validator, the schema validation at submission is not triggered when the mode is "onSubmit" (default). The submission to the action is done, even if the data are not schema compliant. The validation works when setting the mode to "onBlur", "onChange". Any Idea what is wrong?

    • @diegoulloao
      @diegoulloao 5 หลายเดือนก่อน

      Had the same issue. I guess you found the solution…