Next.js 13 Crash Course Tutorial #11 - Client Form Component
Key Takeaways
This video tutorial demonstrates how to create a client form component in Next.js 13, utilizing tools such as Next.js, React, useState, and useRouter to handle form submission and redirect users to a tickets page.
Full Transcript
okay then my friends so what I'd like to do now is make a new page which is going to have a form on it that we can use then to add new tickets so first of all let's make that page and I want it to have the route forward slash tickets forward slash create so to do that we need to make a new folder called create inside the tickets folder and then inside that create folder we need to make a new page.jsx file for the page content right now inside here we can just boilerplate a new react component and I'm going to call it create form now before we write any templates I just want to think back to the discussion we had about server components and client components and remember both types of components are rendered on the server however clients components are also hydrated in the browser to add in any interactivity whereas server components aren't so we said that where there's no kind of local state or interactivity we would use a server component because it doesn't need that hydration but when we did need local state or interactivity then we should use a clients component because it would need to be hydrated in the browser now this page that we're making will have interactivity and some local state to keep track of what a user types into the form Fields so in this case the page component needs to be a client's component and remember all components inside this app folder are server components by default but we can override that by adding at the top of the file in double quotes use clients and that tells next.js that this is a client's component and it needs hydrating in the browser with some JavaScript and that's all we need to do now we can just carry on as normal and make this component as we normally would do now actually before we create this form I think what I'd like to do instead is rename this page to create tickets and then create another component called create form.jsx and I think I'd like to create the form inside this component and make this be the client components and then this can remain as a server component so the page is a server component and we can Nest the create form client component inside a server component we can do that and the reason I'm doing this is because we might have other content on this page in the future that's not part of the form and that doesn't necessarily need to be inside the client component because remember when we looked at that diagram on the next documentation near the start of the series it was basically saying try and make as many things as possible a server component and then just sprinkle in the client components where they're needed so it's only the form itself that needs to be a client component and other things on here in the future the title a little nav bar other information doesn't need to be in that client component does that make sense so let me save this let me go over here and set the top use client because this is the client component I'm also going to boilerplate this component as well and inside here we can make now the form so let me save that first of all and go and Nest it over here we'll have a main tag right here and inside that we'll do an H2 that says text hyphen primary and also text hyphen oops dot text hyphen Center they're the classes I'm applying and this will say add a new tickets and then below that we can have the create form and make sure you import that at the top like so okay so now this is the server component still and this is the client component all right so let's flesh out this form all right so the first thing I'm going to do inside here is to just import a couple of things so I'm going to import use router from next forward slash navigation and the reason I'm importing that is because later on after we submit the form we're going to use the use router hook to redirect the user to the tickets page and also I'm importing you state because I want a little bit of State for the different fields that a user is going to import so the title the body and the priority of the ticket so next I'm going to paste in that little bit of State down here so we have the title and set title and that's equal to use State the initial value is an empty string body and set body empty string to begin with priority in set priority and the default value of that is low but I'm going to make a select field which allows you to choose low medium or high as well and then we have this is loading property and set is loading and that's set to false the idea being when we submit the form I'm going to change this to true so we can show some kind of loading state in the button or something now I'm also going to use const router is equal to use router up here as well so we're basically using this hook so that we have an instance of the router that we can use later on to redirect the user okay so now let's create the form itself so down here I will create the form tag we don't need the action just yet we'll come back to the on submit Handler later on and in fact what I'll do is apply a class to this so class name is equal to and it will be with hyphen one half so that means use half the width of the page and apply it to this form and that's the Tailwind class all right so inside here we need a few different input Fields so what I'm going to do is just copy and paste this from my repo because I think it would be better than you watching me type this out from scratch but I will go through all of this it's a very simple react stuff so we have the first one right here we have a label wrapping the entire thing inside the label text is title and then we have an input field which is required the type is text on change we fire function and call set title and we set the value of that to e dot Target which is this import dot value so whatever they've typed in it then becomes that part of the state up here okay so we're tracking what they're typing and also for the two-way data binding the value of this is equal to the title okay so that's for the title the next one down here oops that needs to say body that's for the body of the ticket this time using the text area again required on change this time we use set body to update the value of the state and the value is equal to body as well and then finally we have a select right here for the priority on change we call set priority this time and the default value of this is remember low up here then we have three options one for low one for medium one for high so they're the three different fields we need we also need now a button to submit this form so let's create that a button like so and I'm going to give this a few props so let's do it on different lines so class name is going to be equal to BTN primary so BTN hyphen primary and then I also want a disabled property and that's going to be equal to is loading so when we set that equal to true and we've already submit the form we don't want them to keep on clicking the button and basically spamming it so we'll disable the button while it's loading is true after they've clicked it once all right so inside this button I want to Output conditionally two different things either add ticket if is loading is false so they've not submitted yet or when is loading is true and we're trying to do something in the background to add that ticket I want to change the text to adding dot dot so let us do that conditional here curly braces and we'll say is it loading and then double Ampersand and then output a span if that is true which says adding dot dot so if it's loading is true we output this text let's do a different one so if not is loading this time double Ampersand then a span if we can spell it and then we'll say add ticket so until we've submitted it shows this once we have submitted and we're loading then we show this all right and I think that's pretty much it so what we can do for now is view this in a browser just to see what it looks like all right so this address forward slash tickets forward slash create we can now see the form obviously if we try to submit something at the minute then it's not going to do anything well it will it will refresh the page because that's the default behavior of forms however we're not actually adding any data anywhere we need a function now to handle the submission of this form so let's create a function now to handle the submission of this form so we'll say const and we'll call this handle submit and we're going to set it equal to an asynchronous function and inside here we want to basically send a post request to Json place not Json placeholder sorry to Json server to add some more data now inside here we get access to the event object and we need that because I want to use e dot prevent default first of all to prevent the default action of a form which is to refresh the page so make sure you spell that correctly prevent default the next thing I want to do is set is loading to be true because after they submit the form I want that to be true so they can't keep clicking the button and also so we see this text instead of this so let us say set is loading and give that a True Value all right so let's create an object to represent the new ticket that we want to submit so I'm going to say const ticket is equal to an object and the title is going to be the title up here so we don't need to do anything else we can just say title same for the body and same for the priority like so and then finally we want a user underscore email and we need to hard code that at the minute because we don't have any kind of authentication or dynamic value for this so we'll just set it to be a string which is Mario at netninja.dev all right sure now we have that ticket we can send a post request to Json server to add that new data to this file over here okay so let's do that I'm going to say const response is equal to a weight Fetch and then the end point we can get from the terminal let's open that up and scroll right up here to where they give us the end point where is it there it is all right copy that and paste it right in here okay and then we also need to pass in a second argument which is an object and right here we can say the method of this is going to be a post request then we want to specify the headers and the headers is going to be an object where we say the content hyphen type is application forward slash Json so we're basically saying the data that we're sending with this is going to be Json and then after that we need to send the body which is the data we want to actually add to the file so we can stringify that by saying json.stringify and then pass in oops spell it right stringify pass in the ticket object and that's all we need to do that's going to send a post request and add this new ticket object to this db.json file okay so after that I want to check the response status and then if we get a good status so 201 which means resource added then I want to basically redirect the user to the tickets page so I can say if response.status is equal to 201 then do something and I will take the router which we have because we use the use router hook right here dots push and then I'm going to push to the tickets page now there's going to be a problem with this which we'll see shortly but for now let's register this handle submit function with this form so I'm going to say on submit is equal to handle submit like so all right so let's give this a whirl in the browser all right so I'm on the create page I'm going to add a new ticket so I'll say my new ticket and then down here blah blah blah for the body and then for the priority we'll say high priority add the ticket all right that worked we've got the loading state but we don't see it right here if we refresh then we should see it but we don't see it to begin with now why is that well it's because we're still using that cached version of the tickets data even though we said we don't want to Cache it we're not actually sending a new request to the server for that page because it's being done browser side so we're seeing the cached version of the page in essence so what we need to do is tell the application to basically in the background refetch this page with the new data so let's go and try and do that so what we could do right here where we redirect the user to forward slash tickets is just before that say router and then do a refresh and what that's going to do is tell the react router to request the route in the background and refetch any data that we need and then when we get to the tickets page it's going to have that fresh data so let's save this and then try it out all right so I'm back on the create page and this time I'm going to say another new ticket oops ticket and then down here blah blah blah and then this is going to be low priority add the ticket and hopefully this time when we get to the tickets page we're going to be able to see that new ticket there we go another new ticket low priority right there so that's work now
Original Description
In this Next 13 tutorial series, you'll learn the basics of Next.js to make a simple project, using the new app router & server components.
🚀🥷🏼Access the entire Next.js 13 Masterclass course on Net Ninja Pro:
https://netninja.dev/p/next-13-masterclass
➡️ Use promo code NEXTNINJA50 for 50% off!
📂🥷🏼 Access the course files on GitHub:
https://github.com/iamshaunjp/nextjs-masterclass
📂🥷🏼 CSS File from course files:
https://github.com/iamshaunjp/nextjs-masterclass/blob/lesson-43/app/globals.css
💻🥷🏼 React Tutorial:
https://netninja.dev/p/build-websites-with-react-firebase
🔗🥷🏼 Next.js docs - https://nextjs.org/docs
🔗🥷🏼 CSS modules in Next.js - https://nextjs.org/docs/app/building-your-application/styling/css-modules
🔗🥷🏼 VS Code - https://code.visualstudio.com/
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Net Ninja · Net Ninja · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Regular Expressions (RegEx) Tutorial #14 - Matching a Username
Net Ninja
Regular Expressions (RegEx) Tutorial #15 - Email RegEx Pattern
Net Ninja
Regular Expressions (RegEx) Tutorial #16 - Finishing Touches
Net Ninja
GraphQL Tutorial #1 - Introduction to GraphQL
Net Ninja
GraphQL Tutorial #2 - A Birdseye View of GraphQL
Net Ninja
GraphQL Tutorial #3 - Project (stack) Overview
Net Ninja
GraphQL Tutorial #4 - Making Queries (front-end preview)
Net Ninja
GraphQL Tutorial #5 - Express App Setup
Net Ninja
GraphQL Tutorial #6 - Setting up GraphQL
Net Ninja
GraphQL Tutorial #7 - GraphQL Schema
Net Ninja
GraphQL Tutorial #8 - Root Query
Net Ninja
GraphQL Tutorial #9 - The Resolve Function
Net Ninja
GraphQL Tutorial #10 - Testing Queries in Graphiql
Net Ninja
GraphQL Tutorial #11 - GraphQL ID Type
Net Ninja
GraphQL Tutorial #12 - Author Type
Net Ninja
GraphQL Tutorial #13 - Type Relations
Net Ninja
GraphQL Tutorial #14 - GraphQL Lists
Net Ninja
GraphQL Tutorial #15 - More on Root Queries
Net Ninja
GraphQL Tutorial #16 - Connecting to mLab
Net Ninja
GraphQL Tutorial #17 - Mongoose Models
Net Ninja
GraphQL Tutorial #18 - Mutations
Net Ninja
GraphQL Tutorial #19 - More on Mutations
Net Ninja
GraphQL Tutorial #20 - Updating the Resolve Functions
Net Ninja
GraphQL Tutorial #21 - GraphQL NonNull
Net Ninja
GraphQL Tutorial #22 - Adding a Front-end
Net Ninja
GraphQL Tutorial #23 - Create React App
Net Ninja
GraphQL Tutorial #24 - Book List Component
Net Ninja
GraphQL Tutorial #25 - Apollo Client Setup
Net Ninja
GraphQL Tutorial #26 - Making Queries from React
Net Ninja
GraphQL Tutorial #27 - Rendering Data in a Component
Net Ninja
GraphQL Tutorial #28 - Add Book Component
Net Ninja
GraphQL Tutorial #29 - External Query File
Net Ninja
GraphQL Tutorial #30 - Updating Component State
Net Ninja
GraphQL Tutorial #31 - Composing Queries
Net Ninja
GraphQL Tutorial #32 - query variables
Net Ninja
GraphQL Tutorial #33 - Re-fetching Queries
Net Ninja
GraphQL Tutorial #34 - Book Details Component
Net Ninja
GraphQL Tutorial #36 - Styling the App
Net Ninja
GraphQL Tutorial #35 - Making a Single Query
Net Ninja
Build Apps with Vue & Firebase - Udemy Course
Net Ninja
Updated Vue & Firebase Course (Udemy)
Net Ninja
Vue & Firebase Real-time Chat (Preview) #1 - Intro
Net Ninja
Vue & Firebase Real-time Chat (Preview) #2 - Project Structure
Net Ninja
Vue & Firebase Real-time Chat (Preview) #3 - Firestore Setup
Net Ninja
Vue & Firebase Real-time Chat (Preview) #4 - Welcome Screen
Net Ninja
Vue & Firebase Real-time Chat (Preview) #5 - Props in Routes
Net Ninja
Vue & Firebase Real-time Chat (Preview) #6 - Route Guards
Net Ninja
Vue & Firebase Real-time Chat (Preview) #7 - Chat Window
Net Ninja
Vue & Firebase Real-time Chat (Preview) #8 - New Message Component
Net Ninja
Object Oriented JavaScript Tutorial #1 - Introduction
Net Ninja
Object Oriented JavaScript Tutorial #2 - Object Literals
Net Ninja
Object Oriented JavaScript Tutorial #3 - Updating Properties
Net Ninja
Object Oriented JavaScript Tutorial #4 - Classes
Net Ninja
Object Oriented JavaScript Tutorial #5 - Class Constructors
Net Ninja
Object Oriented JavaScript Tutorial #6 - Class Methods
Net Ninja
Object Oriented JavaScript Tutorial #7 - Method Chaining
Net Ninja
Object Oriented JavaScript Tutorial #8 - Class Inheritance
Net Ninja
Object Oriented JavaScript Tutorial #9 - Constructors (under the hood)
Net Ninja
Object Oriented JavaScript Tutorial #10 - Prototype
Net Ninja
Object Oriented JavaScript Tutorial #11 - Prototype Inheritance
Net Ninja
More on: Prompt Craft
View skill →Related Reads
📰
📰
📰
📰
I built 42 landing page templates as single HTML files (no npm, no build step)
Dev.to · Segcam spa
Part 7B — Section 2 — React Event Handling Explained: Forms, Event Object & User Input.
Medium · JavaScript
Stop Using window.resize for Everything: A Practical Guide to the ResizeObserver API
Medium · JavaScript
Rendering Lists and Handling Events
Dev.to · Silas
🎓
Tutor Explanation
DeepCamp AI