-
-
Save laere/9485b4d02ad88692b8d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const AddTodo = (text) => { | |
const post = axios.post(API, { text }); | |
//logging purposes | |
post.then(function(response) { | |
return console.log(response); | |
}, function(err) { | |
console.log('Error') | |
return { | |
type: REMOVE_TODO, | |
id | |
}; | |
}); | |
return { | |
type: ADD_TODO, | |
id: nextId++, | |
payload: text | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import ListItem from '../components/ListItem'; | |
export default class List extends Component { | |
constructor(props) { | |
super(props); | |
//reference these functions | |
this.handleOnClick = this.handleOnClick.bind(this); | |
this.clearInput = this.clearInput.bind(this); | |
} | |
handleOnClick(e) { | |
e.preventDefault(); | |
//save input value | |
let inputValue = this.refs.inputfield.value; | |
if(inputValue === '') return; | |
//pass input value to callback | |
this.props.addTodo(inputValue); | |
} | |
clearInput() { | |
//clears input on clear button | |
this.refs.inputfield.value = ''; | |
console.log('This clears the input value'); | |
} | |
renderTodos() { | |
//if items is passed as props | |
if(this.props.items) { | |
//map each item to have item id and item text | |
return this.props.items.map((item) => { | |
return ( | |
//pass removeTodo func to child pass text to child | |
<ListItem removeTodo={this.props.removeTodo} key={item.id} text={item.text} /> | |
); | |
}); | |
} | |
} | |
render() { | |
return ( | |
<div> | |
{/*initiate callback on submit*/} | |
<form onSubmit={this.handleOnClick}> | |
<input type="text" ref="inputfield"/> | |
<input type="submit" value="Add" className="btn btn-primary" /> | |
<input onClick={this.clearInput} type="submit" value="Clear" className="btn btn-primary" /> | |
</form> | |
<ul> | |
{/*render todos*/} | |
{this.renderTodos()} | |
</ul> | |
</div> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import List from '../containers/List'; | |
//action creators | |
import { AddTodo, RemoveTodo, FetchTodos } from '../reducers/reducer_todos'; | |
//reference to store | |
import { connect } from 'react-redux'; | |
//allows use of action creators directly (without dispatch wrapper) | |
import { bindActionCreators } from 'redux'; | |
class App extends Component { | |
constructor(props) { | |
super(props); | |
//reference these functions | |
this.addTodo = this.addTodo.bind(this); | |
this.removeTodo = this.removeTodo.bind(this); | |
} | |
componentWillMount() { | |
// fetch todos | |
//then dispatch them to action creator | |
this.props.FetchTodos(); | |
} | |
addTodo(text) { | |
//add to do | |
this.props.AddTodo(text); | |
console.log('This is the text passed to the AddTodo AC: ' + text); | |
} | |
removeTodo(id, e) { | |
//remove todo | |
this.props.RemoveTodo(id); | |
console.log('This is the ID of the removed todo: ' + id); | |
console.log(e.type, e.which, e.timeStamp); | |
} | |
render() { | |
return ( | |
<div> | |
<h1>Todo List</h1> | |
{/*pass down action creators | |
pass down items state*/} | |
<List | |
items={this.props.items} | |
addTodo={this.addTodo} | |
removeTodo={this.removeTodo} | |
/> | |
</div> | |
); | |
} | |
} | |
let mapDispatchToProps = (dispatch) => { | |
return bindActionCreators( | |
{ | |
AddTodo: AddTodo, | |
RemoveTodo: RemoveTodo, | |
FetchTodos: FetchTodos | |
}, dispatch); | |
}; | |
let mapStateToProps = (state) => { | |
return { | |
items: state.items, | |
text: state.text | |
}; | |
}; | |
export default connect(mapStateToProps, mapDispatchToProps)(App); |
Wow awesome, I will definitely use both thunk and redux-promise-middleware in the future. Thanks again for the help, I learned an absolute ton more about redux and other things, and really feel confident using it again in the future!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can use both!
From the middleware docs
Be careful though because the order you put them in will matter. Since they are chained each middleware will receive the result of the previous middleware.
In your scenario I would put thunk first, then promise middleware. Thunk will allow to dispatch at will, and then if the object you return is in the form accepted for the promise middleware, it will utilize that.
Take a look at the source for redux-promise (it's just 1 file!)
All it does:
payload
is a promisedispatch
from thethen()
block.If it's not a promise then it simply passes the action on to the next thing with
next(action)
, but if it it waits to resolve and then dispatches a new action (which the next middleware/thing receives). If there is another middleware in order after it then that receivesaction
, if not then the reducer gets the action and does its thing.If you're getting more familiar with promises and how redux flows you should notice that redux-promise is super similar to both what you're already doing with axios and most of the examples I gave on reddit. It's removing the boilerplate you would need to write to handle the promise in each action creator and instead allows you to write an action with a
payload
that is apromise
. Then it takes care of executing the promise and dispatching actions depending on the result for you.Also take a look at redux-promise-middleware as it accomplishes the same thing but with a slightly different approach to how it handles the result of a resolved promise. (I prefer redux-promise-middleware).
As an example of using multiple middlewares -- in the app I am building I have this middleware stack (in order):
_REJECTED
type suffix and then attempts to parse an error from the payload and show a toastr notification for a failed api response. (Remember, this happens afterclientMiddleware
so I've already got my api response!)