Using a combination of React, Redux, and Thunk, I have the following:
actions.js
import $ from 'jquery'; import * as types from '../constants/ActionTypes'; import { API_PATH } from '../constants/Config'; export function coursesLoaded(courses) { return { type: types.COURSES_LOADED, courses }; } export function fetchData() { return (dispatch) => { return $.getJSON(API_PATH).then((response) => { dispatch(coursesLoaded(response.result)); }); }; }
reducer.js
import { routerReducer as routing } from 'react-router-redux'; import { combineReducers } from 'redux'; import * as types from '../constants/ActionTypes'; const initialState = { courses: [], }; function main(state = initialState, action) { switch(action.type) { case types.COURSES_LOADED: return { ...state, courses: action.courses, }; default: return state; } } const rootReducer = combineReducers({ main, routing }); export default rootReducer;
The two fragments above sit well, and I feel like they are in line with Redux's intentions. I want to make some changes to the fields returned in the answer before they get into the containers.
For example, the answer might be:
[ { code: "R101", name: "Intro to Redux", author: "Dan" }, { code: "R102", name: "Middleware", author: "Dan" }, ]
And I want to change it (a simple example for simplicity):
[ { code: "R101", name: "Intro to Redux", author: "Dan", additionalProperty: "r101_intro_to_redux" }, { code: "R102", name: "Middleware", author: "Dan", additionalProperty: "r102_middleware" }, ]
Research so far
Option 1 Looking at an example of asynchronous programming on Redux, I see that there is a light touch: https://github.com/reactjs/redux/blob/master/examples/async/actions/index.js#L33
Option Two Looking at other issues related to Stackoverflow, it makes me believe that saving it from actions makes more sense, since gearboxes should be what changes state (but maybe this is not really considered a state): Redux - where to prepare the data
Option three : I have a tendency for middleware to work — this is what normalizes it, but I cannot find examples of non-passive middleware. If the middleware is going here, should the middleware send any SET_STATE action, or can it be updated right there in the middleware?
EDIT
Experimenting with some middleware, for example:
import { lowerCase, snakeCase } from 'lodash'; import * as types from '../constants/ActionTypes'; export default store => next => action => { if(action.type == types.COURSES_LOADED) { action.courses = action.courses.map((course) => { course.additionalProperty = snakeCase(lowerCase(`${course.code} ${course.name}`)); return course; }); } return next(action); }
Everything seems to be in order - is this middleware intent really? The initial question is where is this perfect place?