1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 37x 10x 6x 12x 5x 5x 24x 1x 24x 27x 1x 10x 6x 6x 1x 4x 4x 4x | import { ACTION_FETCH_START, ACTION_FETCH_COMPLETE, ACTION_FETCH_FAILURE, ACTION_UPDATE_LOCAL, ACTION_RESET_LOCAL, } from './constants'; import handleActions from './utils/handleActions'; const getName = action => action.payload.name; const getRequestedAt = action => action.payload.requestedAt; const getRespondedAt = action => action.payload.respondedAt; const getJSONResponse = action => action.payload.json; const getError = action => action.payload.error; const getPreviousError = (state, action) => state[getName(action)] ? state[getName(action)].error : null; const includeString = (element, array) => array.indexOf(element) !== -1; const resetOrKeepValue = (field, action, currentData) => ( includeString(field, action.payload.data) ? undefined : currentData[field] ); const updateWith = (state, name, obj) => ({ ...state, [name]: { ...state[name], ...obj, }, }); const reducer = handleActions({ [ACTION_FETCH_START]: (state, action) => updateWith( state, getName(action), { lastRequest: getRequestedAt(action), isFetching: !action.error, isInvalidated: true, error: action.error ? getError(action) : getPreviousError(state, action), }), [ACTION_FETCH_COMPLETE]: (state, action) => updateWith( state, getName(action), { isFetching: false, isInvalidated: false, lastResponse: getRespondedAt(action), data: getJSONResponse(action), error: null, headers: action.meta, }), [ACTION_FETCH_FAILURE]: (state, action) => updateWith( state, getName(action), { isFetching: false, isInvalidated: true, error: getJSONResponse(action), headers: action.meta, }), [ACTION_UPDATE_LOCAL]: (state, action) => updateWith( state, getName(action), { data: action.payload.data, }), [ACTION_RESET_LOCAL]: (state, action) => { const name = getName(action); const currentData = state[name] || {}; return updateWith( state, name, { lastRequest: resetOrKeepValue('lastRequest', action, currentData), isFetching: resetOrKeepValue('isFetching', action, currentData), isInvalidated: resetOrKeepValue('isInvalidated', action, currentData), lastResponse: resetOrKeepValue('lastResponse', action, currentData), data: resetOrKeepValue('data', action, currentData), error: resetOrKeepValue('error', action, currentData), } ); }, }); export default reducer; |