Redux 像显示/隐藏加载屏幕这样的操作应该由相关操作的还原者处理还是由操作创建者自己生成?

Redux 像显示/隐藏加载屏幕这样的操作应该由相关操作的还原者处理还是由操作创建者自己生成?,redux,Redux,考虑到在许多情况下可能会出现一些全局视图(例如,显示加载屏幕),为该行为创建一个动作创建者/动作对还是让相关动作的减速器处理转换更合适 这很难简明扼要地描述,为了说明我的意思,这里有几个例子。哪一个更好,为什么 A. B 我更喜欢A,因为对我来说,在一个地方描述这些行为似乎比复制状态管理的逻辑更明智,但我在redux社区听到一句格言,行动应该描述发生了什么或正在发生什么,而不是命令。在这种情况下,这仅仅是一个语义问题,其中“异步操作”一词比“显示加载”更好吗?思考这段特定代码将如何演变。 用这个

考虑到在许多情况下可能会出现一些全局视图(例如,显示加载屏幕),为该行为创建一个动作创建者/动作对还是让相关动作的减速器处理转换更合适

这很难简明扼要地描述,为了说明我的意思,这里有几个例子。哪一个更好,为什么

A. B
我更喜欢A,因为对我来说,在一个地方描述这些行为似乎比复制状态管理的逻辑更明智,但我在redux社区听到一句格言,行动应该描述发生了什么或正在发生什么,而不是命令。在这种情况下,这仅仅是一个语义问题,其中“异步操作”一词比“显示加载”更好吗?

思考这段特定代码将如何演变。
用这个来做决定

例如,您可能有多个可以加载的项目集。您最终可能会有两个并列的项目列表,或者一个在另一个下面。因此,您希望它们具有单独的
isLoading
状态,就像它们具有单独的ID列表一样

这两个选项中的代码将如何更改?减少操作似乎更简单,因为这样可以使特定列表的
isLoading
状态与其他相关信息保持接近,也不用担心忘记在action creator中重置其状态。所以在这种情况下,我会选择B选项

另一方面,如果我们讨论的是一个用例,比如显示一个UI通知,我可能会把它作为一个单独的操作来启动。它的存在完全独立于导致它的服务器响应:通知需要在一段时间后隐藏,两个通知可能同时出现在屏幕上,等等。因此,对于这个用例,选项a似乎更适合

一般来说,你应该问问自己:

  • 这段代码可能会如何发展
  • 这两个动作真的是同一个动作,还是只是相互关联但又相互独立

谢谢,这非常有用。你对“行动不应该是命令”的格言有什么看法?Redux中唯一的格言是“还原者必须是纯粹的”。其他一切都取决于你和你的应用程序中有意义的东西。很酷,听起来很合理。再次感谢。有趣的是,我在redux的学习过程中忽略了我所看到的许多观点,并相信我自己的直觉和判断,即每个应用程序应该如何运行。这很令人耳目一新。
function showLoading () {
    return 'SHOW_LOADING';
}

function hideLoading () {
    return 'HIDE_LOADING';
}

function fetchPostsRequest () {
    return 'FETCH_POSTS_REQUEST';
}

function fetchPostsSuccess () {
    return 'FETCH_POSTS_SUCCESS';
}

function doSomethingAsync () {
    return dispatch => {
        dispatch(showLoading());
        dispatch(fetchPostsRequest());
        // other logic
        dispatch(hideLoading())
        dispatch(fetchPostsSuccess());
    }
}

function rootReducer (state = {}, action) {
    const payload = action.payload;

    switch(action) {
        case 'SHOW_LOADING':
            Object.assign({}, state, {isLoading: true})
            break;
        case 'HIDE_LOADING':
            Object.assign({}, state, {isLoading: false})
            break;
        // other reducers for handling success/request stuff
    }
}
function fetchPostsRequest () {
    return 'FETCH_POSTS_REQUEST';
}

function fetchPostsSuccess () {
    return 'FETCH_POSTS_SUCCESS';
}

function fetchPostsFailure () {
    return 'FETCH_POSTS_FAILURE';
}

function doSomethingAsync () {
    return dispatch => {
        dispatch(fetchPostsRequest());
        // good
        dispatch(fetchPostsSuccess());
        // bad
        dispatch(fetchPostsFailure());
    }
}

function rootReducer (state = {}, action) {
    const payload = action.payload;

    switch(action) {
        case 'FETCH_POSTS_REQUEST':
            Object.assign({}, state, {isLoading: true})
            break;
        case 'FETCH_POSTS_SUCCESS':
            Object.assign({}, state, {isLoading: false /* other logic */})
            break;
        case 'FETCH_POSTS_FAILURE':
            Object.assign({}, state, {isLoading: false /* other logic */})
            break;
    }
}