We have a completed flag that can be boolean. That's going to be this checkbox here. And then we can just add, we can set our created ad and updated ad that we basically get for free from Prisma. We're not going to use these two fields throughout the workshop, so you can feel free to skip them, but I'm going to add them here.
Now I'm going to stop my server. I'm going to run npm run DB push. What this is going to do is compile the schema file, make changes to my database, my SQLite database, and then also have the TypeScript client generated. So I'm going to run that npm run DB push. And once this is complete, I can go back to npm run dev, and I have my server running. So I'm going to close the schema file here. I'm going to refresh this, and everything should still work as expected. We haven't really made any changes to the application. We've just added a new model to the database.
But now what we can do, is instead of this array, this page here is something that's called a server component. If you haven't used server components at any point, you can kind of think of them as a get endpoint on your server, which means this component actually runs only on the server and not on the client. This doesn't run on in the browser, which means we can just directly access our database here. We can say await DB.todo.findmany, and we can make this an async function. So now this function looks less like a React component and looks more like a request handler on an express endpoint or an API endpoint of some sort. Yeah. So you can think of this as the function that runs only on the server, which is why we can just async await our data from our database here, and we can render them as JSX. So now if I save it here, what's going to happen is you should see no todos found, because now we're actually fetching these todos from the database, but there's nothing there yet, so we see no todos found. And this is just a very basic idea of server components here. We're going to dig into this a little bit more. Now I won't really have scope or time to explain a lot of server components stuff throughout this workshop, so a lot of times, if you have questions, again, feel free to put it in chat, but I would really encourage kind of holding onto them, and maybe we can chat about them after the workshop, or you can visit the next JS documentation.
But now let's add some interactivity. Right now if we go here, this does not work. So if I click add, it doesn't actually do anything. If I click refresh, there is no todo, because we don't have the logic for adding a todo into the database. So let's go into our Add Todo component and see what's happening. So this is a form, as expected. We have an input field here for this input, and then obviously we have the button that we can click, or we can just hit enter. But on the on submit handler, we are not actually doing anything. We get the value out of the form data. We call this Add Todo function, but all it's doing is logging it into the console. So if I pop up in the console here, let's move it to the bottom, and can I add this todo. If I press enter, it's just being logged in the console. There's nothing else happening.
And this component here, because we have marked this file as use client, what this basically means is these React components are the React components that we know and love. We have hooks here. We have event handlers. So these are not server components, they're just regular React components. But this page file, this is a server component, which is why we can access the database inside it. So for that error, Nelly, make sure the int, the i is supposed to be capital, not lowercase. So all the types in a Prisma schema start with a capital letter. Cool. Okay, so this is a regular React component. How do we make it add something to a database, our Add Todo component? So let's first make sure that this Add Todo component comes as props. So let's define some props here. And let's say that Add Todo, the type of the Add Todo prop is that it takes in a string and it returns a promise of void. Which means this Add Todo function, instead of being defined in here, is now something we are passing into this Add Todo component. And we can just call it here.
Okay, so now the function doesn't need to be defined in a component, now it needs to be passed in. What's the big deal? This client component is being rendered by a server component, which means, again, now that we are in page, we are in full server mode. Which means we can give it this function. The Add Todo function that we just defined on the client, that this component needs this input, needs this prop. And we can define it on the server side to kind of act as another API endpoint. So here we can just say, await db.todo.create with this title. And we need to give it the completed default value of false. Okay, so what is going on here? I just talked about how server components can be thought of a get endpoint. So when you make a get request to a server, you get back a bunch of data, or you get back an HTML page. Similarly, a server component is what you get when you make a get request, you get back some UI. This function here, which is also called an action, you can think of it as a post request to the server. Now one thing that we need to mark here is, call it use server. This directive here, similar to this use client directive, is obviously to tell the bundler that this is a special function that needs to be treated especially. But it also tells us as a developer that this is a function that's basically a post endpoint on our server. We don't explicitly have to attach it to a URL and add the parsing request and do all the request response stuff. But that's the mental model. This function here is going to be called when someone makes a post request to our server. And then when this function is passed into our actual React component, it's automatically going to be changed to a function that makes the post endpoint instead of us actually sending this code down to the client. Again we can get into a lot more details about this, but I want to keep that out of the scope of the workshop.
Comments