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



假设您有一些全局视图(例如显示加载屏幕),您可能希望在许多情况下发生,那么为该行为创建操作创建者/操作对还是让相关操作的reducer处理转换更合适?

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

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
    }
}
B

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

我更喜欢A,因为在一个地方描述这些行为而不是复制状态管理的逻辑对我来说似乎更明智,但我在redux社区听到了一个格言,即操作应该描述发生或正在发生的事情,而不是命根式命令。在这种情况下,这只是一个语义问题,像"ASYNC_OPERATION_START"这样的术语比"SHOW_LOADING"更好吗?

想想这段特殊的代码将如何演变。
用它来做决定。

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

两个选项中的代码将如何更改?拥有更少的操作似乎更简单,因为这使您可以将特定列表的isLoading状态保持在与其相关的其他信息附近,并且也不用担心您忘记在操作创建器中重置其状态。这里我选择选项b

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

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

  • 这段代码可能会如何演变?
  • 这两个动作真的是相同的还是它们只是相关但独立的?

最新更新