2.2 - Concept App Component
In this part, we're going to lay out our parent component and get things set up for moving forward. The first thing we're going to add to our ReactConceptsApp
is going to be state so that we can incorporate the concepts that we added as our array of data in the last module. If you want, you might want to refer back to the state module and just refresh your memory. Try to anticipate how we will set up state in the component.
lodash and concepts import
In order to be able to use that list of concepts in this file, we need to import them first. While you're at it, we're also going to import a package called lodash
.
Lodash is a JavaScript library which provides utility functions for common tasks. It should already be in your package.json
file.
Go ahead and add the following imports to the top of your file.
Set up state
Now that we have our concepts, we can set up our state for this application. As usual we can do this in our constructor()
. Go ahead and add the following to your ReactConceptsApp
.
Remember that you can run console.log(this.state.concepts)
to see what is happening in the state.
render()
Let's also go ahead and put in our render()
method. We need a way to display our concepts from the state. Let's start by just displaying them under general concepts.
At this point, if we try to run the application, what will happen? Will it work? Try it, if you'd like.
If you do, you'll see that we get an error that says the following:
"Objects are not valid as a React child (found: object with keys {text, done}). If you meant to render a collection of children, use an array instead."
We're working with an array here. We need some logic to display these objects. We don't have that. Let's do that now.
ConceptList
Instead of trying to put all the logic in one component, we can create a new component to handle displaying all of the concepts. Since we're passing it a whole bunch of concepts, we want to create a List component first.
Go to ConceptList.js
in our concept-list-app folder. We'll be passing this component props, and don't need it to access any methods relating to state or anything, so we can make this a functional component.
We're going to follow that pattern here, let's start by getting our component set up. In this component we'll need lodash for some easy calculations. Let's add the folloinwg:
List components in general are a pretty common pattern in React. This is where you do any calculations on the entire list, and then render each individual part of the list through a child component, usually through a map or a loop.
Formatting
After we get it set up we're going to need to take our concepts and format them in a way where they can be passed to a child component to render individually. By using lodash
, we can sort them by whether or not the task is done so that the list is more useful to the user. We also want to create individual components for each concept. We can do this easily using map! Go ahead and write the following in your ConceptList component:
Important reminder, in React you need unique keys when children, so here we need unique keys.
If we just pass in concept
, react will throw this error Encountered two children with the same key, [object Object]. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
return the items
Now that we have items
, with a bunch of Concept
components ready, we just need to return them, and that's the last step of this list component. Go ahead and make sure your whole component looks like the code below:
Notice the '_' gives us access to an assortment of lodash methods. In this case we're using sortBy
. We're going to sort by the concepts that are marked 'done'. This will act as a container for the ones that are crossed off, and help us, as we map, to put them on the bottom.
Concept.js
Now, we need to create our Concept
child component. This component just needs to render every concept, and that's about it. Go into Concept.js
in our concept-list-app folder. Since we don't need to access the state in this component and we're only using it for rendering, we can make this a functional component.
We need this child component to run a function, so we pass it in props to display the concepts for us. We can start with framing our component. We know we're going to pass it a concept, and a method to change whether or not the list item is clicked. Let's call this toggle
.
Go ahead and start setting up your Concept component like below:
done method
Next we need some method for our list items to call when they're clicked. We need to also call the toggle method that we're passing as props. We need this to work onClick and for it to run the toggle method.
Go ahead and put this method in your Concept component. The console log is there so we can eventually see what we are running.
render
Lastly, we just need to render our concept. If the concept is done, we want to show it struck through, and if it isn't, we don't. Then we need a thing that users can click that will toggle our done
method. Go ahead and type out the rest of the component below:
You'll want to be able to spot that one and discuss it. Basically, if the concept.done is true, the text will show as crossed off. If it is not done, it will just show the text. That's what's in the curly braces. After that expression is a simple button that will fire off done
when clicked for that list item.
Final Code
Our whole Concept
component should look like this:
Now that we've got our Concept List and Concept set up, we're ready to go back to our parent component in the next step to add in all of the logic!
Last updated