Introduction to the JAMStack Wiring Data to the UI
Transcript from the "Wiring Data to the UI" Lesson
>> Effectively what's happening here is we've written a serverless function that could be called by any app to load in these to dos. And that is pretty dang cool, I think. So at this point, Let's do that. Let's actually show these two do's and let's set up our front end.
[00:00:26] And so again for convenience, I'm just using Gatsby. So I'm gonna to do an install here of yarn add gatsby react and react-dom. And then I am also going to add in a gatsby-config, so that Netlify Dev knows to use this as a Gatsby site. So that's just an empty file.
[00:00:51] Inside of here, we're going to create a source folder. In that source folder, we're gonna create pages and index.js. And this is gonna to be our whole Apple live in this component. So I'm going to start out by importing react from react. Then I will, we're just gonna export that as our default.
[00:01:16] So export default component and we can just return a main. That main is going to have a heading in it. And I'm gonna use the CSS modules again. So I guess we can import that as well, styles from index.module.css. Let's make sure that exists, so it doesn't complain at us.
[00:01:47] And we'll come back to that later. So I'm gonna use styles., what would be a good name for this, heading. And we'll say JAMstack Todos. Let's turn on wrap. Okay. Then, we're going to. This is very meta, or TODO is to add todos, right? So what we need to do here is make a request to our server list function to load those todos and then we need to get those into some format that we can display on the screen.
[00:02:33] So I'm going to manage that using, we're gonna use axios again, so we'll import axios from axios. And then we're also going to use some effects or some hooks. So the first one that we need is a useEffect. We're gonna load right on the initial, right when the component mounts we want to send off a query for those Todos.
[00:03:00] And then we're gonna useState to keep track of the Todos, cuz it's just one object. So the first thing is going to be, we'll get the status and then we're gonna set the status. And we're gonna set it up as loading. And we're doing something similar to what we did with the form state management, where we'll set up some states and react accordingly.
[00:03:26] I'll talk a little bit more about the approach, because we're gonna do a couple of fancy things as we go. But they're all done for good reason. [SOUND] And then we're going to set up a initial Todo State of null. That means that down here, I can say, if we have todos, then I want to do something.
[00:03:53] And if we don't have todos, then I want to add a class name of styles.loading and we'll say loading todos. And if I go back to the homepage here, and start Netlify Dev. Okay, so this is our basic app. It's gonna show us loading todos. Good, good. So then we wanna figure out how we're gonna actually show these todos.
[00:04:35] And the way that I'd like to do it is as a list of just plain old list items. And we can do that by the todos are going to be an array. And so we're gonna need to figure out how to actually make that work. Okay, so we've got this set up.
[00:05:05] Now we need to get those todos into our app. To do that, I'm gonna set up a useEffect hook. And that useEffect hook is going to retrigger anytime that the status changes. And the reason for that is that we're gonna have a loading state and then when it finishes loading, we'll go to loaded, but we wanna be able to retrigger loading when we do things like delete todos and stuff like that.
[00:05:37] There are ways that we could manage this, like loading them and putting them into a cache and then we would go in and rewrite that cache or something. We're opting to solve this problem with a hammer. So what's gonna happen is anytime we make changes, we're going to make a fresh request for all todos and put that up on the screen.
[00:05:55] So there are more efficient ways to solve this problem, but they're also significantly more difficult to implement and so we're not gonna get there today. So what we'll start out by doing is we'll say, if this has been canceled, we're gonna to stop working. So we'll default to say it hasn't been cancelled, the canceled is false.
[00:06:18] And then if the status is not loading, we're also gonna bail out, so we'll just return immediately and not do anything. And if we get to here, that means that we're actually ready to load some stuff. So let's get axios kick in. We'll hit up api/get-all-todos and then we will get the result.
[00:06:42] And that result, we're gonna check if canceled has been set to true, because if so, then we don't wanna do anything, right, we'll just bail out of that result and stop trying to work. The reason for that is that there are situations that you'll hit in an app or maybe on mounts, maybe you end up going to another screen and you don't want React to try to update something that's not there.
[00:07:05] It'll throw big gnarly errors and it looks very broken. So it's easier just to say, hey if we get to a point where we're not ready to do anything, just cancel. And the way that we can make that work, is we can tell React that whenever we exit this function, we're just gonna set canceled to true.
>> There's a typo on 12, line 12.
>> J at the end.
>> Thank you. So if we get in here, so basically what this means now, is that when this component starts, it's going to run this. And then whenever the component unmounts, this function will run, which will set canceled to true.
[00:07:48] Which basically means, if we navigate away from this page or we otherwise unload, this will tell React to just bail out of finishing this thing. So once we get down into here, we can say, if the result.status does not equal 200, that means we've got a problem. So we're gonna console error and we'll say Error loading todos.
[00:08:12] And then we will also just log whatever happened. So we'll log the result. And then to make sure that it doesn't try to do anything else, we'll also return. And finally we're at the point where we can assume we safely have todos and we're actually ready to work with them.
[00:08:31] So we will setTodos up here to be the result.data.todos, because if we remember, we sent back todos. So the result gives us our data. Body gets renamed to data, I'm not a hundred percent sure why. But we'll get back these todos here. And so we can set those as our todos and that means that we'll be able to actually do something with them.
[00:09:02] Then we're gonna set the status to loaded, so that it doesn't try to load them again. And the only way that we can retrigger that is by changing that status, so we can trigger a reload now by changing the status to loading. So let's save this. And we change the number of hooks, so that's why it exploded just now.
[00:09:24] And so we gave it a hard coded value, but notice that it did find todos and it's trying to display them now. So let's write a todo component, that can show this data. And for the sake of keeping things a little bit cleaner, I'm going to create an actual todo component and that component lives down here somewhere.
[00:09:54] Okay, so let's import React from react. And I'm also going to import styles from todo.module.css, which we need to make sure exists. And we can define that component, call it todo. And then it's going to accept our todo item, which will have that ID completed and text. So then in here we can return.
[00:10:37] The paragraph and that paragraph is going to have a class name of styles.text. And we can just show the todo.text. And then if it's completed we want to make it look a little bit different, right, so we're gonna turn this into. Let's make that wrap. If the todo is completed, then we will show styles.completed.
[00:11:20] I can export that as our default. And now that we're ready on that, we can come out to the index file, and we can actually use this. So let's import it. Components/todo. And then down here, to avoid a React error, we're gonna give this a key of todo.id.
[00:11:50] And then I'm also gonna give it a class name of styles.todo. And this one also is gonna get a class name of styles.todos Inside of it, we will pass in the todo. And that should give us. All right, now we've got todos coming in from the database and they look the way we want.
[00:12:27] Need a little bit of styling to make this actually functional, so let's do that real quick. I'm gonna pull up the index.module.css here and let's just write out a couple styles. So, do a couple global overrides, we'll set the color to be 444. That dims it just a little bit.
[00:12:51] Then we can set the font family to sans serif. Okay. Then down here we can set up a heading, make that heading little bit darker. And we'll set the text align to center. Okay, it's starting to work, that's starting to get where we want. Let's set up the todos, to be border-top, 1 pixel solid there.
[00:13:17] And then we can do a list-style of none. Then we can set up some margin, do a 2rem at the top and bottom and center it vertically. We also wanna set up some max width of 500 pixels. And then we can do padding of 0 to make that function a little bit better.
[00:13:43] And we can see, if we zoom out a little bit, that that starts to center, but we are not going that wide. So next, we'll set up a todo and that's going to be designed for Flexbox. CSS Flexbox is amazing. If you haven't taken the time to learn it, it is very worth the deep dive.
[00:14:04] So let's give it a border-bottom of 1 pixel solid ddd. And then we're gonna set the box sizing to border-box. We'll set the display to flex. And then we're also gonna set justify-content to space-between. Dave Matthews totally ruined this one for me. So every time I declare this, I'm in my head, I was like the space between.
[00:14:40] And it almost made me not wanna use Flexbox anymore. [LAUGH] So we'll set margin of 0, we'll give it a little bit of padding and finally we'll set the width to be a 100%. Very last thing is we want that loading state to just be centered, so it doesn't fly off to the left on us.
[00:15:05] So now, when we reload the page, our Todos load in, they look okay, that looks all right. So, then, I'm going to pull up this todo module. And there was just one piece I needed to fix, which is that we want to clean up that paragraph just a tad.
[00:15:26] So we're gonna set the margin to 0 and we'll set the width to a 100%.