2.8 Section Component: Displaying Sections
Individual pages will be composed of multiple sections. In this lesson, we'll build the
Section component. For now, we'll focus on displaying the section content.
1.Getting Started6 lessons, 27:04
2.Building the Application13 lessons, 1:29:43
3.Conclusion1 lesson, 00:44
2.8 Section Component: Displaying Sections
In the previous lesson. We began rendering our pages. And we got some good features down. We can move from page to page. However what we need to look at next. Is rendering our sections within the page. And we're going to start this lesson in the firebase app dashboard. Firebases really cool in this way we can actually make changes to the data. Right here live. So I'll click this plus sign here, and let's add a section. And then instead of giving it a value a click this plus button over here. And we can give sections its own properties. So look at that one with a name and zero. And I'll give it value Hello world. And let's add some mark down in there. And then let's make another one here. And we'll give it a name of one. And we'll give it a value of one to three in a markdown list format. So very, very basic. All right. And now we have two sections in our Dogs page. Now the reason I've done it this way is because we're going to start by rendering those sections as read only, and then in the next lesson, we'll look at adding editing capabilities to those sections. So since we're just doing read only in this lesson, we need some data to work with. So back here in our page component, we have this comment here that we made, render sections. Now as you might imagine, each section is going to be a component of its own. So let's create a new file, src/components/section.js. Once again, we'll start by importing react. And there's another package that we're going to need in this module, and that is the markdown package, because of course we're storing the markdown code in our database. However we need to render it a HTML. So, we need a way to convert from markdown to HTML. So here in the terminal let's do npm install markdown and we'll install version zero point five and don't forget to add the save flag. Once that has installed, I'll go ahead and start our server back up and now we can head back to our section dot js file. In here, we'll import markdown from markdown. And because of the way this package structure works, we'll have to use destructuring there. And now we can actually begin our class. So let's do export default class Section extend React.Component. And once again, we're going to start with the state. However, we're not just going to assign directly to the state property as we've done previously. And here's why. There's a lot of state that we need to manage for this section. Not only do we have the content as both markdown and HTML. But we also need to consider the editing capabilities. So we need to know whether the user is logged in or not. Basically, whether they can edit or not. Also we need to know whether they are currently editing a given section, or whether a section is locked because someone else is currently editing it. So you could say there's a lot of different moving pieces to this section. And we're going to need to make sure all of these different states are receiving the right values at several different times throughout our application. So we're going to write our own custom function here called Get State. Now this isn't a special react name or anything like that. This is a function that we are going to call ourselves. We'll expect this function to be passed a set of properties. These are either gonna be the properties that this component was initialized with or, if the page changes, these will be the new properties that have been reassigned to this component. Inside of this arrow function we want to return an object. However, the curly braces are of course blocks and text as well. So we need to wrap these in parentheses so that our function will return this object and not think we're creating a block. Inside our getState object here, we're going to start with two very simple properties. First will be content and this is going to be as markdown. We can get this from props.section.content. So the section object from the database will have a content property which will be the actual markdown content. Then we want to convert that to HTML. So we're going to have an HTML property too. Now it's possible that this section will have no content right now. So we'll have to use a expression here. We'll say, if props.section.content exists, then we'll call markdown.toHTML and we'll pass it props.section.content. However, if there's no content right now, we'll just set our html to be an empty string. All right, so now we have to actually call this function to set our state. Now, you might think that we could just use state = this.getState. However, when we're setting a class property like that, we don't have access to the properties that we need as a parameter forget state. And so that's not going to work. Instead, what we can do is create a constructor function. This constructor function will be called when our component is an initialized, and the first parameter to this constructor are the properties that are react element has. Now because our section class extends another class React.Component, we have to call the super constructor at the very top of our own constructor function. So I'll call super and I'll pass at the properties that we've received. Then after that we can set this.state. Which is our state property. And here inside constructor we can call this docket state. Because we have access to those properties that we need to send in to the get state function. So now we can create our render function. We're going to start with something very very simple here. So that we can make sure that our content and HTML values are what we expect them to be. So let's just return an empty differ now. However inside this render function. We will also console.log.this.state. That way we can see that those content in HTML state properties are what we expect them to be. Now we can't just refresh our page just yet because we have to come back to Page.js here. And actually use our section component. So right here we have our render sections comment. Let's take that out. And instead say if this start state DOT sections. Meaning if our page actually has sessions to render. Then we'll overwrite that section's array that we created. And we'll set it to Object.keys and we'll get the section keys, and then we can map over those keys. Just as we've done before with our list of pages The arrow function that we'll use here will take an ID as the only parameter there. And will return a new section. Of course this means that we have to jump to the top of our file and import our section component. But after we do that, we can come back here and add some properties to this section. Of course we'll have to give it a unique key first. We can do this with the idea of the section. And then we have to pass the actual section data into this section component. So we'll create a perimeter named section. And its value will of course be. This dot state dot sections. Square bracket idea. All right. So that should be all we need to do to actually render all of our sections. So if we come back to the browser and refresh the page, you can see that we have two objects being printed out to the console here. However, the values are not what we would expect the content values are undefined. And therefore the HTML values are empty strings. However we do get two of them. Now we did add two sections to the dogs page in the firebase database. So the fact that we're getting to here means that something is going right. However obviously something else is going wrong because neither of these sections have the right values inside of them. Now I'm sure you may have noticed what the problem was when we created those values initially in our firebase database. I set the sections up to be strings instead of to be objects with a content value. So let me go back to firebase here and I'll delete the values that I added at the beginning of this lesson. And then let's create a new sections object. Inside of that will create an object with the name of zero. And inside that will create an object with the name of content. And they hello world content. Then inside section will create another object with an idea of one. And inside that will have an object with the property. Content and with the value of our one two three list items. All right. So I can go ahead and save those values to the database. And now if I come back to our application and refresh the page, you can see that the values were getting printed out here, are exactly what we would hope for. The content is the mark down, and the HTML property is the mark down converted into HTML. It looks like we are having a problem with the new line characters that I wrote in the markdown. And we're just getting an unordered list with a single list item instead of three. However we are getting unordered list and a list item so that is a positive thing. So that's good it will have to fix that. When we get to editing mode. So let's come back to our section.JS file. And in our render function here. Let's create content variable which will be a span. And here we run into something that reactor really doesn't like. And that is we want to set a string as HTML within our document. Now there are some security risks to this, however, we want to go ahead and do it anyway. And react will let us do it, however, they force this to be an uncomfortable process so that you do realize that it can be a bad idea. We need to include the property name dangerouslysetInnerHTML. And then inside the value of that property. We need to pass an object with the key. Double underscore HTML. And then reset our HTML. As the value for that property. So now this band should have the HTML that we want inside of it. Let's replace that empty div that we're returning with an actual section element. And inside of this, we can just put the content that we have just rendered. Now if we return to the browser and refresh the page, you can see that we're Actually getting our content displayed properly. We have hello world. Displayed and world as bold as we sat in the Mark down. And we have an ordered list with our single item there displaying underneath it. So we are successfully taking to mark down sections and converting them to HTML. This is coming along pretty well. Let's close out this lesson by adding a little bit of styling to the sections. This will become more useful later on when we start adding an editing mode. First, let's create an array of classes here. By default, every section will have the classes row and section. So we can put those in an array and then we'll add a class name property to our section. And we can set the value of this to be classes.join. By a space. Now the row class will be provided by the skeleton framework, however the section class is our own. So let's go ahead and create a public/style.css function, and let's style .section. All right. So, we'll do something really basic here. We'll give it a bit of padding. We'll give it a border radius. And we'll set the border to one pixel of solid white. Now, right now, we can't see the border. However, later on, when a user hovers over a certain section. If they have the ability to edit that section. We want the border to turn gray so they can kind of get an indication that they could edit that. We'll give it a bit of a margin too, we'll set that to one 1em. And then let's just clean up some margin here. The last child of the section, will set the margin bottom to be zero, so that there's not quite as much space between the different sections. Now I'm pretty sure we already planned for this stylesheet. If we open up our index file yeah you can see we have a second link element there in the head for /style.css. Excellent. So if we head back to the browser and refresh it. It looks like we do have a bit of space there. So that's great. All right. So in this lesson, we have successfully displayed our page sections to our visitors. The next step will be to allow them to edit these sections.