With zod validation, I tried one and if you look at what he did, the parsed variable returns an object with the parsed data but when you put it in a try catch, you can catch the instance of ZodError and get it's property formErrors.fieldErrors which will return all the errors.
I learn by doing. Not by reading. This was exactly what i needed. I implemented this, saw it working, learnt how and why it worked and added it to my project. Perfecto. Thanks bro.
This is great! Can you do a follow up with some more advanced stuff? Like, how do I handle optimistic updates & failures/rollbacks, how do I ensure my TODOs mutation state is synced across all pages/components that might need it, how can I update TODOs state from within the app code (not as part of a form submission). In other words -- is it possible to use this new paradigm to replace most of what Redux does?
Hi Lee and engineers 👋 Thank you for the smooth video. Watching this I came to a few questions: 1. What is the reason to move from the previous approach? How much performance are we winning here? It would be nice to see some good and old before/after comparisons. 2. Many people are asking for more advanced cases, but are those even possible? I don't see modern forms without the usual rerendering that we used until now. Thank you and I hope for more such videos in the future!
Really nice video, your explanations are always amazingly informative, thanks a lot 🔥Also, can’t wait for the stable release of the “cache” function, good to know that it’s coming soon
This was a great explaination... the docs were pretty hard to follow and understand. None of the examples connect together so its hard to get a full picture of what is going on.
1. Use HTML input validation attributes. 2. Validate on server, returning the names of dependent inputs in the result of form action, or implement a client-side solution if you need instant feedback. 3. ??? This is not in scope, data formatting is highly subjective. But if you need a specific format on the server, deserialize the form data there. 4. Use name="some_field[]" as the name of one or more inputs, i.e. checkboxes.
Thanks a lot for your explanations and demo it was really useful for me. The only question I didnt find answer on is how to handle multiple actions within single form
3:21 - wait a minute. Maybe I'm not understanding something, but doesn't schema.parse throw an error if the data is incorrect? And if yes, shouldn't it be inside the try block?
i would like to see binding extra arguments and formless use of server actions with starttransition as i feel there's a lot of interesting things that can be done with these methods.
Hello Lee On minute 7:24, when you delete a todo and use revalidatePath, the code shown does not work. You would never be able to get the returned message (on lines 50 to 52). Ireproduced your example. This is probably because the todo is removed from component tree, and therefore the state is reset.
How would you recommend approaching submitting a form that relies on state being built up over time? For example: a form with multiple inputs including an input that builds an array of values through something like a multi-select input or an input collecting a list of emails?
well if it relies a lot on user interaction to progressively enhance the form (dependent fields and so on) you can’t really just use the server for that unless you submit the form at several points and return different forms dependent on the server side state (storing it in memory or KV store)
Suppose we have a table in a Next JS page and the table has a filter (client) component with interactivity. When we hit Apply, how do we pass the filter values from the client child to the server parent component. (The parent fetches the data and renders the table). I can see many suggestions to pass the data as params or queryParams using revalidate or nav methods of next. That works fine for a simple values like ID or search params. For example, if it is not just an ID but an object (advanced filter similar to the one in Amazon), should we just pass the entire object via the search params and make the URL bloated with so many values or are there any alternate way to communicate from client child (filter) to server parent component (where data is fetched) ??
When starting off this example, is it necessary to do some configuration before it can be used? It is immediately giving me a error upon first npm run dev - Error: connect ECONNREFUSED ::1:5432 Do i need to create a server it can communicate with before this example can be used?
Everybody has Javascript disabled until it's loaded. Especially for users with slow internet, we can provide the default experience even without the Javascript.
@@aravindsamala9528and why would you submit a form before the page is loaded? Considering we are not in 00s and there are also controls which are using js
When cloning the project locally and filling in my vercel database credentials I get "Error: db error: ERROR: relation "todos" does not exist Caused by: ERROR: relation "todos" does not exist" And when im tryting to deploy this straight from the template to vercel It also won't build. Type error: '"react-dom"' has no exported member named 'experimental_useFormState'. Did you mean 'experimental_useFormStatus'? 1 | 'use client' 2 | > 3 | import { experimental_useFormState as useFormState } from 'react-dom' | ^ 4 | import { experimental_useFormStatus as useFormStatus } from 'react-dom' 5 | import { createTodo } from '@/app/actions' 6 | error Command failed with exit code 1. Something broken with the template?
What if this form was a search form and below you wanted to see filtered ToDos? In this case, the server action should return data based on the search criteria but how do you return this data? The todos area should not fill by a full db search now, it should fill with the results of the sever action. You have to use the search term from the form. I am missing something here and I cannot do it (for the moment). Also, I am not sure any more which component should be a server component and which one should be a client component. Is my approach wrong? Are server actions ONLY for mutations? Any suggestions? (All the videos show server actions mutating data. I want just a search) Thanks...
Hey Lee, great content as always! Will you do a new video regarding next auth and providers like credentials, google and github? Credentials is mostly covered in the nextjs learn course, but google auth is not. I've been wondering if we should use api routes to handle this or is there any way using form actions as well. Thanks and keep up the great work!
I just installed I have error on '"react-dom"' has no exported member named 'experimental_useFormState'. Need I an special npm install for use experimental react feature ?
@@leerob still doesn't work after adding ts-ignore error TypeError: (0 , react_dom__WEBPACK_IMPORTED_MODULE_4__.experimental_useFormState) is not a function or its return value is not iterable
@@BaileySimrell did you find a solution for this problem because i encountered the same problem exept i am not using the experimental_useFormState, just the useFormState, been to multiple GitHub Issues, but didn't figure it out
Does revalidatePath adds some payload to the response in conjunction with the data you return on your server action or revalidatePath streams the new state to acknowledge the client to revalidate cache and update UI and then the server action return statement is hit, streams another response and the client updates again?
Hey, could you maybe shed some light on Auth + XSRF on this? As it's submitting a form and if cookies are used for Auth, this would be vulnerable to XSRF attacks, right?
Lee, is there any way to simulate the following scenario: I have a component called user.tsx and another called filters.tsx, using useSearchParams I can pass a "state" to users.tsx and use this data from filter.tsx to change the data displayed on my screen. This with react query is very simple, because if there is any change in the queryKey (the filters in this case) it automatically invalidates the current query and redoes the fetch. My question is: Is there a way to obtain a similar result using only server actions and fetch making requests to a api?
This is great. Does anyone have a tutorial on how to integrate this with AWS AMPLIFY GRAPHQL calls? I think the limitation is that AWS is only up to like NextJS 13.4
i'm getting an error while running the dev server: VercelPostgresError - 'missing_connection_string': You did not supply a 'connectionString' and no 'POSTGRES_URL' env var was found.
Is there a video how to perform unit testing on this form? I tried setting it up but getting errors about 'useFormState' Any help would be appreciated.
is there a reason why SubmitButton is a separate component instead of just being a part of AddForm. can we not use both useFormStatus and useFormState hooks in the same component?
I'm new to nextjs13 , in react I was using react query to handle remote data coming from api and show isloading on screen and also optimistic UI , and I want to know does next 13 need any library to handle those functions or I just need to create fetch request in any server component I want. my current next project is a blog
por que se reinica el componente cuando envio la data , nunca llega el console.log? export async function createMemberTeam(formData: FormData) { 'use server'; console.log('createMemberTeam', formData); }
Had a very bad experience trying to work with method="GET" in next js forms. Nothing works. Always does a full page refresh. Didn't have these many probems in remix
is adding some data using hidden input are recommended ways by nextjs team? is it a best practices or i can try another way? why just not passing the hidden data in initial argument of form hooks , it looks like more simpler rather than adding additional html element
you can use .bind() on the action to pass through additional args without creating hidden forms. the data you bind will always be the first argument, so if you're using useFormState, you'll have something like: function serverAction(bindData, prevState, formData) it's mentioned in the next docs in the api reference section
@@leerob that would be amazing if you could show some cool new do some standard well known stuff like CRUD(this video) and authentication and then maybe even streaming data and websockets. Love you guys at the NEXT.js team, this magical framework really makes fullstack development a joy and as simple as it should've always been.
it has no types, that's all. the function is there and it works, but it's just missing from the type declaration. it does cause builds to halt though, including on vercel lmao
i solved this by creating a success key with a simple boolean. i have a useEffect block that watches the state; if success is true, then it will trigger setState(false) on the modal and close it. i also fire a toast that displays the success message, or an error message if it fails
Can you do an example where JavaScript is disabled, server side validation fails, and we need to show an error state to the user. This doesn't seem to work in the example provided.
I will install the latest next update in my project to test but earlier when I tested, forms were not working without JavaScript and redirect in a server action was failing 😢
Great showcase as usual, but how many ads does this video have 😂😂😂? .... anytime you touch the time scroll? ad, pause and play? ad, fast forward or rewind? ad. ... always 2 ads back to back 🤣🤣🤣🤣🤣, Thanks for the breakdown
I think that's New Moon. Can't link it here but it's on GitHub, with theme files for Chrome DevTools and a lot of terminals too. It's really excellent for HTML, CSS, JS and React/JSX with TypeScript.
Why server actions can't be used directly as a value to onClick attr for a button and just passed the data as an argument to function and nextjs will serialize automatically to send the request on server?
Server actions are serialized to URL endpoints on the output, that is then handled by Next and directed to the correct server action handler. onClick are for client-side only events, and you cannot serialize function from server -> client. This the same reason you cannot pass a function to event handlers within server components.
@@dealloc then we should use server actions only for forms? I mean if i have a button that when triggers has to change some data on server then api endpoints are more clean? Bcs if i have to make it a server action i have to enter all the things that i want to send as a payload (for example in apis), as a hidden form fields, isn't that gets more complicated?
@@ahmedivy It depends on what you're doing-for simple server-side mutations, this is the approach to use as it can be progressively enhanced (i.e. work without JavaScript), and with React's upcoming hooks to handle form state, loading, optimistic updates, etc. It's not a silver bullet solution; e.g. you cannot use form submissions to recieve callbacks from a request (i.e. send data, waiting for a response from the server), in those cases you should use regular fetch, or a library like React Query/swr to handle client-side fetching. But this limits you to only support users with JavaScript, which may in some cases be what you want, and in other cases not. These are _Server_ actions. It's in the name ;)
from what i can figure out from using it, it takes your server action that takes the previous "state" object and the form data as arguments and returns a promise which resolves the "state" object. with this, it appears to split the function in two, separating the object (so it can be consumed by the app or some sort of state management hook) and the action (so it can be consumed by the form).
To forward that data in `FormData`, to be used in the Server Action. www.w3schools.com/tags/att_input_type_hidden.asp#:~:text=Definition%20and%20Usage,when%20the%20form%20is%20submitted.
@@leerob oh I see. Is it because now the DeleteForm component has its own tag so it needs some "hidden" input values acting as ID in the FormData for server action?