Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the sensible place to modify response data in redux?

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 snippets above sit well, and i feel like they align to the intentions of Redux. I want to now do some modifications to the fields that are returned in the response, before they hit the containers.

For example, the response might be:

[
    { code: "R101", name: "Intro to Redux", author: "Dan" },
    { code: "R102", name: "Middleware", author: "Dan" },
]

And I want to change it to (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 thus far

Option One Looking at the async example on Redux, I can see there is a light touch to the response here: https://github.com/reactjs/redux/blob/master/examples/async/actions/index.js#L33

Option Two Looking at other Stackoverflow questions, it leads me to believe keeping it out of the actions makes more sense, as reducers should be what modifies state (but perhaps this doesn't really count as state?): Redux - where to prepare data

Option Three I have an inclining that this is the job of middleware - being that's how normalizr handles it, but I can't find any non-passive middleware examples. If middleware is the go here, should the middleware be dispatching some kind of SET_STATE action, or is it free to update state right there in the middleware?

EDIT

Experimented with some middleware, such as:

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);
    }

It seems to work fine - is this indeed the intention of middleware? Original question holds - where it the ideal spot?

like image 535
Chris Avatar asked Mar 31 '16 07:03

Chris


1 Answers

As for me I do this kind of things in the action (either coursesLoaded or fetchData).

Here are the reasons why:

  • This is not store material, this is just external data management, so nothing to do with reducers which are supposed to change the STATE of the store
  • Different reducers might actually need the same corrected data, imagine you have another reducer that gathers all additionalProperty for achiving purposes for example, so doing it in the action ensures that the right data is sent to all reducers.
  • This is not a typical job for a middleware, this is only specific to one action, whereas middleware would be useful if it was used the same way by a bunch of actions. Plus using middleware is more obscure and separates it from the reader. Having action-> reducer is much more simple and does not have any major disadvantage.
like image 153
Mijamo Avatar answered Oct 02 '22 20:10

Mijamo