在Redux中链接async和sync操作以计算初始状态

Chaining async with sync actions in Redux for calculating initial state?

本文关键字:操作 计算 初始状态 sync Redux 链接 async      更新时间:2023-09-26

很抱歉收到长文本。。。我正试图找出最好的方法来连锁一些需要等待对方来计算初始状态的动作。重新选择可能会有所帮助,但我很难弄清楚如何适应。我使用的是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"
}

bookdetailedNotes来自GET调用(使用fetch)notesByCategory是由我的代码计算的(目前在reducer中…),我还需要将activeCategory初始值设置为第一个计算的类别(示例中的Vital)。以下是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部分。我觉得这个计算可能不应该在减速器中。有什么建议吗?

您可以避免这种情况,方法是不将派生数据存储在您的状态中,而是使用选择器进行计算(尽管不一定要使用reselect)。

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

您的选择器可以访问整个存储,因此在返回activeCategory的选择器中,您可以有一些逻辑来返回存储中的activeCategory(如果不是null)或基于可用类别的一些默认值(如果是null)。

将您的存储视为"真相的来源",并使用选择器从中获得所需的一切,这还有防止不一致的额外好处,因为您可以确信存储是正确的,并且独立于其他数据。

通常,默认状态应由减速器处理。一开始,您在reducer中得到null状态,并且应该提供一些"初始"状态。

在您的情况下,这通常是通过默认参数(=List())的方便语法来使用的。