1.apply redux-thunk middleware
import { applyMiddleware, createStore, compose } from 'redux';
import thunk from 'redux-thunk';
import createLogger from 'redux-logger';
import reducers from '../reducers';
var middlewares = compose(applyMiddleware(thunk), autoRehydrate());
export default function configureStore() {
const store = createStore(reducers, undefined, middlewares);
return store;
}
2.start & end action types
//todo action types
export const START_FETCH_ALL_TODOS = 'START_FETCH_ALL_TODOS';
export const FETCH_ALL_TODOS = 'FETCH_ALL_TODOS';
3.fetch flow
import * as types from '../constants/ActionTypes';
import * as APIs from '../constants/ServerAPIs';
function shouldFetchAllTodos(state) {
const data = state.todos;
if (data && data.isFetchingAllTodos) {
return false
}
return true;
}
export function fetchAllTodos() {
return async (dispatch, getState) =>{
//verify
if(!shouldFetchAllTodos(getState())){
return Promise.resolve();
}
//dispatch fetch start action
dispatch({type: types.START_FETCH_ALL_TODOS});
//fetching
const response = await fetch(APIs.allTodos);
//response
const data = await response.json();
//dispatch fetch end action
return dispatch({
type: types.FETCH_ALL_TODOS,
data
});
}
}
4.reducer
export default function todos(state = initialState, action) {
switch (action.type) {
case types.START_FETCH_ALL_TODOS:
return Object.assign({}, state, {isFetchingAllTodos: true});
case types.FETCH_ALL_TODOS:
return Object.assign({}, state, {
isFetchingAllTodos: false,
data: action.data.data.reduce(function (pre, cur) {
//remove duplicates
!pre.find( key=> key.id===cur.id) && pre.push(cur);
return pre;
}, [...state.data])
});
...
...
default:
return state
}
}
5.dispatch & render
...
componentDidMount(){
//fetch data from server
this.props.actions.fetchAllTodos();
}
...
...
renderLoading = () => {
if (this.props.todos.isFetchingAllTodos) {
return (
<View style={styles.loading}>
<Text style={styles.loadingText}>Loading...</Text>
</View>
)
}
return null;
}
...