Last active
March 23, 2019 12:30
-
-
Save rowlandekemezie/f5558dd00ce7ab6e22e8027dac6ba762 to your computer and use it in GitHub Desktop.
Using redux thunk to for async
This file contains hidden or 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
// Dependencies | |
const { applyMiddleware, createStore } = Redux; | |
const { connect, Provider } = ReactRedux; | |
// GitHub API | |
const gitHubApi = (username) => { | |
// Put your Api call here | |
}; | |
// redux-thunk implementation | |
// source: https://github.com/gaearon/redux-thunk/blob/master/src/index.js | |
// Redux-thunk handles most use cases for async actions in your application | |
function thunkMiddleware(store) { | |
return function(next) { | |
return function(action) { | |
if (typeof action === "function") { | |
return action(store.dispatch, store.getState); | |
} else { | |
return next(action); | |
} | |
} | |
} | |
} | |
// Action creator | |
const getUserSuccess = (user) => { | |
return { | |
type: 'LOAD_USER_SUCCESS', | |
user | |
} | |
} | |
// User reducer implementation. | |
// Simply returns the new user object to the store on LOAD_USER_SUCCESS. | |
// Always remember to return state as the default case | |
const userReducer = (state = {}, action) => { | |
switch (action.type) { | |
case 'LOAD_USER_SUCCESS': | |
return action.user; | |
default: | |
return state; | |
} | |
}; | |
// fetchUserDetails thunk | |
// It returns a function that takes dispatch as the first argument. When AJAX | |
// request is successful, it dispatches getUserSuccess action with user object. | |
const fetchUserDetails = (username) => { | |
return dispatch => { | |
return gitHubApi(username) | |
.then(user => { | |
dispatch(getUserSuccess(user)) | |
}) | |
.catch(error => { throw error; }) | |
} | |
} | |
// React component | |
class UserProfile extends React.Component { | |
constructor() { | |
super(); | |
} | |
// We call our thunk here. | |
// componentDidmount is for dynamic behavior, side effects, AJAX, etc. | |
componentDidMount() { | |
this.props.fetchUserDetails('rowlandekemezie'); | |
} | |
render() { | |
const { user } = this.props; | |
return ( | |
// Display the user value received from the store | |
) | |
} | |
} | |
// Setup store | |
const store = createStore(userReducer, applyMiddleware(thunkMiddleware)); | |
// Map the store's state to component's props. | |
// This way you keep the component in sync with Redux store | |
const mapStateToProps = (state) => ({ | |
user: state | |
}); | |
// Wrap the thunk with dispatch method and | |
// merge them to component's props | |
const mapDispatchToProps = (dispatch) => ({ | |
fetchUserDetails: (username) => dispatch(fetchUserDetails(username)) | |
}); | |
// Connect React component to Redux store with React-redux connect() | |
const UserProfilePage = connect( | |
mapStateToProps, | |
mapDispatchToProps)(UserProfile); | |
// Mount the component to the DOM | |
// Provider makes available the store's state to component's below | |
// the hierarchy via connect() call. | |
const element = document.getElementById('root'); | |
ReactDOM.render( | |
<Provider store={store}> | |
<UserProfilePage /> | |
</Provider>, | |
element, 0 | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment