You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.6 KiB

Comments Component Build

This builds off of what was built by the end of the Webpack Lesson.

Lesson Objectives

  1. Create Comments component
  2. Create CommentsList component
  3. Create CommentsForm component
  4. Display an array of comments
  5. Make form add new comments
  6. Create the ability to add new comments to the Comments component
  7. Have the Comments form call the Comments component's addComment function

Create Comments component

Create a directory for components:

mkdir js/components

Rename mylib.js to comments.jsx and move it in the components dir:

mv js/mylib.js js/components/comments.jsx

Create the Comments class in js/components/comments.jsx:

import React from 'react';

class Comments extends React.Component {
    render(){
        return <h1>Comments Component</h1>
    }
}

export default Comments;

Import the Comments component into js/index.js:

import ReactDOM from 'react-dom';
import React from 'react';
import Comments from './components/comments.jsx';

ReactDOM.render(
    <Comments></Comments>,
    document.querySelector('main')
);

Create CommentsList component

Create a separate file for the comments list:

touch js/components/commentslist.jsx

In js/components/commentslist.jsx create a basic component:

import React from 'react';

class CommentsList extends React.Component {
    render(){
        return <ul>
            <li>comments list</li>
        </ul>
    }
}

export default CommentsList;

Import CommentsList into js/components/comments.jsx:

import React from 'react';
import CommentsList from './commentslist.jsx'

class Comments extends React.Component {
    render(){
        return <section>
            <CommentsList></CommentsList>
        </section>
    }
}

export default Comments;

Create CommentsForm component

Create js/components/commentsform.jsx:

touch js/components/commentsform.jsx

Write a basic component in js/components/commentsform.jsx:

import React from 'react';

class CommentsForm extends React.Component {
    render() {
        return <form>
            <input type="text" placeholder="author"/><br/>
            <textarea placeholder="comment"></textarea><br/>
            <input type="submit" value="Post Comment"/>
        </form>
    }
}

export default CommentsForm;

Import CommentsForm into js/components/comments.jsx:

import React from 'react';
import CommentsList from './commentslist.jsx'
import CommentsForm from './commentsform.jsx'

class Comments extends React.Component {
    render(){
        return <section>
            <CommentsList></CommentsList>
            <CommentsForm></CommentsForm>
        </section>
    }
}

export default Comments;

Display an array of comments

In js/components/comments.jsx, create a constructor in the Comments class that initializes an array of comments:

constructor(props){
    super(props);
    this.state = {
        comments: [
            {
                body:'this rox',
                author:'bob'
            },
            {
                body:'no, you rox',
                author:'sally'
            },
            {
                body:'we all rox',
                author:'zagthor'
            }
        ]
    }
}

Now pass it off to the CommentsList component:

<CommentsList comments={this.state.comments}/>

In js/components/commentslist.jsx loop through the comments prop and display the comments:

import React from 'react';

class CommentsList extends React.Component {
    render(){
        return <ul>
            {this.props.comments.map((comment, index) =>
                <li key={index}>
                    {comment.author} says: "{comment.body}"
                </li>
            )}
        </ul>

    }
}

export default CommentsList;

Create the ability to add new comments to the Comments component

In js/components/comments.jsx set the comments state property to an empty array:

constructor(props){
    super(props);
    this.state = {
        comments: []
    }
}

Add the ability to add a new comment in js/components/comments.jsx

  • you have to use this.setState or react won't know the state has changed and won't refresh the DOM
addComment(comment){
    this.state.comments.push(comment); //this alone won't notify React to update the DOM
    this.setState({
        comments: this.state.comments
    });
}

Now bind the addComment function in the constructor for js/components/comments.jsx:

constructor(props){
    super(props);
    this.state = {
        comments: []
    }
    this.addComment = this.addComment.bind(this);        
}

Have the CommentsForm call the Comments component's addComment function

In js/components/comments.jsx create a property on the CommentsForm element called handleSubmit and pass it this.addComment:

render(){
    return <section>
        <CommentsList comments={this.state.comments}></CommentsList>
        <CommentsForm createComment={this.addComment}></CommentsForm>
    </section>
}

In js/components/commentsform.jsx, create a handleSubmit function in the CommentsForm class definition:

handleSubmit(event){
    event.preventDefault();
    console.log('posting comment');
}

Don't forget to create a constructor that binds handleSubmit in js/components/commentsform.jsx:

constructor(props){
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
}

Now call it on form submit in js/components/commentsform.jsx:

return <form onSubmit={this.handleSubmit}>
    <input type="text" placeholder="author"/><br/>
    <textarea placeholder="comment"></textarea><br/>
    <input type="submit" value="Post Comment"/>
</form>

Create references to the comment textarea and author input element in js/components/commentsform.jsx:

<input ref="author" type="text" placeholder="author"/><br/>
<textarea ref="body" placeholder="comment"></textarea><br/>

In the handleSubmit function of js/components/commentsform.jsx, log this element's value:

handleSubmit(event){
    event.preventDefault();
    console.log(this.refs.author.value);
    console.log(this.refs.body.value);
}

Now call the handleSubmit function that was passed into the CommentsForm component by the Comments component:

handleSubmit(event){
    event.preventDefault();
    this.props.createComment({
        body: this.refs.body.value,
        author: this.refs.author.value            
    });
}