使用Redux中的同步操作链接异步以计算初始状态?

时间:2016-05-09 20:03:15

标签: javascript redux react-redux redux-thunk

抱歉长篇文章... 我试图找出最好的方法来链接一些需要等待彼此计算初始状态的动作。可能重新选择会有所帮助,但我很难弄清楚如何适应它。 我正在使用ImmutableJS,但我将使用标准JSON来描述我的麻烦。初始状态应该是:

{
"book": {
"id": 1,
"title": "THE book",
"notes": [
  1,
  2,
  4
]
 },
 "detailedNotes": [
{
  "id": 1,
  "text": "Just a note",
  "categories": [
    "Vital"
  ]
},
{
  "id": 2,
  "text": "Testing",
  "categories": [
    "Vital"
  ]
},
{
  "id": 4,
  "text": "Doodling",
  "categories": [
    "Relevant"
  ]
}
],
"notesByCategory": [
{
  "Vital": [
    1,
    2
   ]
 },
 {
  "Relevant": [
    4
  ]
 }
 ],
 "activeCategory": "Vital"
}

book detailedNotes 来自GET调用(使用fetch)。 notesByCategory 由我的代码计算(目前在reducer中...),我还需要将 activeCategory 的初始值设置为第一个计算类别(示例中的重要)。 这是actions.js和reducer.js的相关代码:

        //in actions
    export function fetchBook(id) {
        return function (dispatch) {
            return fetch('/api/book/' + id)
                .then(json => {
                        dispatch(receiveBook(json));
                        dispatch(fetchDetailedNotes(json['notes']));
                    }
                );
        }
    }
    export function fetchDetailedNotes(ids) {
        return function (dispatch) {
            return fetch('/api/notes/?ids=' + ids.join())
                .then(json => dispatch(receiveDetailedNotes(json)))
        }
    }
    export function receiveDetailedNotes(detailedNotes) {
        return {
            type: RECEIVE_DETAILED_Notes,
            detailedNotes
        }
    }

    //in reducer
    function detailedNotesReducer(state = List(), action) {
        switch (action.type) {
            case actions.RECEIVE_DETAILED_NOTES:
                return fromJS(action.detailedNotes);
            default:
                return state
        }
    }
    function notesByCategory(state = List(), action) {
        switch (action.type) {
            case actions.RECEIVE_DETAILED_NOTES:
                return extractNotesByCategory(state, action.detailedNotes);
            default:
                return state
        }
    }

还有减速器组成,我省略了它。 现在,我想将初始的 activeCategory 设置为第一个类别,但我有一个问题,我不知道在哪里放这个。我必须先等待计算出状态的 notesByCategory 部分。我觉得这个计算不应该在减速器中。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您可以通过不在您的状态中存储派生数据来避免这种情况,而是使用选择器计算它(尽管您不必为此重新选择)。

选择器实际上只是一个函数,它通过mapStateToProps传递状态,并导出容器组件作为道具获取的内容。

您的选择器可以访问您的整个商店,因此在返回activeCategory的选择器中,您可以使用某些逻辑返回商店中的activeCategory(如果不是null)或某些默认值可用类别(如果null)。

将您的商店视为“事实来源”,并使用选择器从中获取您需要的所有内容,这有助于防止出现不一致,因为您可以确信商店是正确的,并且与其他数据无关。

答案 1 :(得分:0)

通常,默认状态应由您的reducer处理。一开始你在reducer中得到null状态,你应该提供一些'初始'状态。

在您的情况下,这通常使用默认参数({{1}})的便捷语法。