哪里是修改redux中响应数据的合理位置



使用React、Redux和Thunk的组合,我得到了以下内容:

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

减速器.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;

上面的两个片段很好,我觉得它们符合Redux的意图。我现在想在响应中返回的字段到达容器之前对它们进行一些修改。

例如,响应可能是:

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

我想把它改为(简单的例子):

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

迄今为止的研究

选项一看看Redux上的异步示例,我可以看到这里的响应很轻松:https://github.com/reactjs/redux/blob/master/examples/async/actions/index.js#L33

选项二看看其他Stackoverflow问题,我相信将其排除在操作之外更有意义,因为减速器应该是修改状态的东西(但也许这并不真正算作状态?):Redux-在哪里准备数据

选项三我倾向于这是中间件的工作——这就是normalizer处理它的方式,但我找不到任何非被动中间件的例子。如果中间件是首选,那么中间件应该调度某种SET_STATE操作,还是可以自由更新中间件中的状态?

编辑

用一些中间件进行了实验,例如:

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

它似乎工作得很好——这确实是中间件的意图吗?最初的问题是——理想的地点在哪里?

对我来说,我在行动中做这类事情(coursesLoadedfetchData)。

原因如下:

  • 这不是存储材料,这只是外部数据管理,因此与本应更改存储状态的还原器无关
  • 不同的reducer实际上可能需要相同的校正数据,例如,假设您有另一个reducer,它收集所有additionalProperty以达到目的,因此在操作中这样做可以确保向所有reducer发送正确的数据
  • 对于中间件来说,这不是一项典型的工作,它只针对一个操作,而如果一组操作以相同的方式使用中间件,则中间件会很有用。另外,使用中间件更为晦涩难懂,并将其与阅读器分离开来。有动作->减速器要简单得多,没有任何主要缺点

或者您可以使用选择器,并将原始文件保存在redux存储中。

const mapStateToProps = state => {
  courses: mySelectorThatAddsFields(state.courses),
}

相关内容

  • 没有找到相关文章

最新更新