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.

161 lines
3.1 KiB

# Integrate Comments Component With Redux
This builds off of what was built by the end of [the comments build lesson](Comments.md)
## Lesson Objectives
1. Install Redux
1. Create the Store
1. Make CommentsList Subscribe to the Store
1. Make CommentsForm Dispatch Actions
1. When an Action Occurs, make CommentsList Update State
1. 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`:
```javascript
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:
```javascript
import store from '../store.js';
```
Once the component mounts, subscribe to the store:
```javascript
componentDidMount(){
store.subscribe(function(){
console.log(store.getState())
});
}
```
## Make CommentsForm Dispatch Actions
In `js/components/commentsform.jsx`, import the store:
```javascript
import store from '../store.js';
```
In the handleSubmit function, dispatch an `ADD` action:
```javascript
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:
```javascript
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`):
```javascript
componentDidMount(){
store.subscribe(() => {
this.setState({
comments: store.getState()
});
});
}
```
Now use that state variable instead of the `comments` prop:
```javascript
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:
```javascript
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`:
```javascript
handleSubmit(event){
event.preventDefault();
store.dispatch({
type:'ADD',
comment: {
body: this.refs.body.value,
author: this.refs.author.value
}
});
}
```