2.4 - Concept List Component

Our last step is to figure out how to create new concepts to add to our app.

The first thing we're going to do is create a new component called NewConcept.js in our concept-list-app folder. This is where we'll handle the input and pass information back up to our parent component ReactConceptApp to handle adding it. This will need an input at the very least. Before we focus on our child component, let's figure out the logic we'll need in our parent component first.

createConcept

The first thing we'll need is a method to be able to create a new concept. Let's create this new method in our ReactConceptsApp conmponent underneath our constructor. All we're going to need to do is push the new concept to our state, and call setState() to set our new state. Type the following code into the ReactConceptsApp component.

    createConcept(text) {
        this.state.concepts.push({
            text,
            done: false
        });
        this.setState({concepts: this.state.concepts});
    }

render()

Then, we're going to need to render our NewConcept component, and pass it the method we just created so that it can use it. So in our render() method, above our general concept h2, we're going to write the following.

<NewConcept createConcept={this.createConcept.bind(this)} />

As a reminder, when methods need access to things like setState, they cannot be written as arrow functions, and also they must be bound to the correct this, so that they can access setState.

Now, the only thing we have left to do is import NewConcept at the top of our file. Underneath your other imports, write the following:

import NewConcept from './NewConcept';

NewConcept Component

Now that we have our ReactConceptsApp setup to use NewConcept, we need to finish up the logic in this component. We need a way to capture users input, and upon pressing a button, using the createConcept method being passed to this component. Go ahead and make your NewConcept component look like this:

import React, { Component } from 'react';

export default class NewConcept extends Component {
    create(event) {
        event.preventDefault();
        let text = this.refs.newConceptText.value;
        if (text) {
            this.props.createConcept(text);
            this.refs.newConceptText.value = '';
        }
    }

    render() {
        return (
            <form onSubmit={this.create.bind(this)}>
                <label>New Concept:</label> <input type="text" ref="newConceptText"/> <button className="button" type="submit">+</button>
            </form>
        );
    }
}

refs

So, in order to avoid using state in this component, since we're handling all state changes in the parent component, we need a way to be able to capture input from a form. One way to do this is using refs.

Refs cannot be used with functional components, which is why this component isn't one.

React can find the input based on the ref and grab the value of it when the user submits this form. Then, in our create method, we are, if there is text, taking that and passing it to the createConcept method. Lastly, we're resetting the value to nothing, so that the user can add more concepts if desired.

And that's it!! Your Concept List app should now be able to handle adding new concepts!

Challenge Time!

  • Challenge #1: use the lifecycleMethods defined at the bottom of concepts, to make a list of lifecycle methods specifically, similar to our list we just made (specifically include the ability to toggle them on and off )

  • Challenge #2: find a way to delete concepts entirely off the list

Last updated