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.

3.1 KiB

Integrate Comments Component With Redux

This builds off of what was built by the end of the comments build lesson

Lesson Objectives

  1. Install Redux
  2. Create the Store
  3. Make CommentsList Subscribe to the Store
  4. Make CommentsForm Dispatch Actions
  5. When an Action Occurs, make CommentsList Update State
  6. Remove Unnecessary Code

Install Redux

npm install redux --save-dev

Create the Store

Create js/store.js:

touch js/store.js

Write a basic store that handles an ADD action and a default:

import { createStore } from 'redux'

let comments = function(state = [], action){
    switch(action.type){
        case 'ADD':
            return [...state, action.comment];
        default:
            return state
    }
}

let store = createStore(comments);

export default store;

Make CommentsList Subscribe to the Store

In js/components/commentslist.jsx, import the store:

import store from '../store.js';

Once the component mounts, subscribe to the store:

componentDidMount(){
    store.subscribe(function(){
        console.log(store.getState())
    });
}

Make CommentsForm Dispatch Actions

In js/components/commentsform.jsx, import the store:

import store from '../store.js';

In the handleSubmit function, dispatch an ADD action:

handleSubmit(event){
    event.preventDefault();
    this.props.createComment({
        body: this.refs.body.value,
        author: this.refs.author.value
    });
    store.dispatch({
        type:'ADD',
        comment: {
            body: this.refs.body.value,
            author: this.refs.author.value
        }
    });
}

When an Action Occurs, make CommentsList Update State

Set up a state property in js/components/commentslist.jsx for comments:

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

when an action occurs, set the state property (we'll need to use an arrow function for proper bind of this):

componentDidMount(){
    store.subscribe(() => {
        this.setState({
            comments: store.getState()
        });
    });
}

Now use that state variable instead of the comments prop:

render(){
    return <ul>
        {this.state.comments.map((comment, index) =>
            <li key={index}>
                {comment.author} says: "{comment.body}"
            </li>
        )}
    </ul>
}

Remove Unnecessary Code

  • We no long need to store anything in js/components/comments.jsx
  • We also don't need to pass anything to child components:
class Comments extends React.Component {
    render(){
        return <section>
            <CommentsList></CommentsList>
            <CommentsForm></CommentsForm>
        </section>
    }
}

js/components/commentsform.jsx no long needs to call this.props.createComment:

handleSubmit(event){
    event.preventDefault();
    store.dispatch({
        type:'ADD',
        comment: {
            body: this.refs.body.value,
            author: this.refs.author.value
        }
    });
}