# 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.

```javascript
import _ from 'lodash';
import { concepts } from './concepts';
```

## 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`.

```javascript
constructor() {
    super(); 
    this.state = { concepts: concepts };
}
```

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.

```javascript
constructor() {
    super(); 
    this.state = { concepts: concepts };
}

************ add code below constructor*************
    render() {
        return (
            <div className="main">
                <div className="mainDiv">
                    <h1>Concept List App</h1>
                    <p>Use the list below to toggle concepts that you do or do not understand. Note that this will update when you refresh the page.</p>
                    <h2>General Concepts</h2>
                    {this.state.concepts}
                </div>
            </div>
        );
    }

************* end add **************
}
```

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:

```javascript
import React from 'react';
import _ from 'lodash';
import Concept from './Concept';

const ConceptList = ({concepts, toggle}) => {


}
export default ConceptList;
```

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:

```javascript
    let conceptsSorted = _.sortBy(concepts, 'done');
    let items = conceptsSorted.map( (concept) => 
    <Concept concept={concept} key={concept.text} toggle={toggle}/>
    );
```

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:

```javascript
import React from 'react';
import _ from 'lodash';
import Concept from './Concept';

const ConceptList = ({concepts, toggle}) => {
    let conceptsSorted = _.sortBy(concepts, 'done');
    let items = conceptsSorted.map( (concept) => 
        <Concept concept={concept} key={concept.text} toggle={toggle}/>
    );

    return (
        <ul>
            {items}
        </ul>
    );
}
export default ConceptList;
```

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:

```javascript
import React from 'react';

const Concept = ({concept, toggle}) => {

}

export default Concept;
```

## 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.

```javascript
const done = (event) => {
    event.preventDefault();
    toggle(concept);
    console.log("Props:", concept, toggle);
}
```

## 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:

```javascript
    return (
        <li>
            {concept.done ? (<del>{concept.text}</del>) : (concept.text)} <a href="" onClick={done}>✓</a>
        </li>
    );
```

The question mark in the above code? Remember the [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator).

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:

```javascript
import React from 'react';

const Concept = ({concept, toggle}) => {
    const done = (event) => {
        event.preventDefault();
        toggle(concept);
        console.log("Props:", concept, toggle);
    }
    console.log('concept:', concept);
    return (
        <li>
            {concept.done ? `<del>${concept.text}</del>` : {concept.text}} <a href="" onClick={done}>✓</a>
        </li>
    );
}

export default Concept;
```

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!

[Finish Up Concept List App Parent](https://eleven-fifty-academy.gitbook.io/javascript-301-reactfundamentals/part-8-apps/2.0-concept-list/2.3-concept-component)
