reactjs - React Redux 处理每个组件特有的错误/成功消息的正确方法

标签 reactjs redux react-redux

问题概述

以下是发送错误/成功消息的标准方法,至少教程是推荐的:

{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', success: 'yay', response: { ... } }

{ type: 'FETCH_POSTS', status: 'error', error: 'Oops' }
{ type: 'FETCH_POSTS', status: 'success', response: { ... } }

但是,我遇到的问题是这些错误/成功消息将显示在监听特定reducer每个组件内正在处理这些操作。

示例场景:

假设您有一个todo应用程序,它具有添加编辑删除三个操作,但是这三个操作都这些操作是从 UI 方面的单独页面执行的。它们都由同一个 todo reducer 处理。

此外,提供用于触发这些操作的 UI 的所有组件都通过 ma​​pStateToProps 监听此 todo 缩减器,以接收 todo 更改 (与本例无关)成功和错误消息:

function mapStateToProps(state) {
    return { 
        success: state.todo.success,
        error: state.todo.error,
    }; 
}

{!!this.props.success && <p>{this.props.success}</p>}
{!!this.props.error && <p>{this.props.error}</p>}

上述问题 问题在于,无法区分添加待办事项错误编辑待办事项错误删除待办事项错误

因此,如果添加待办事项触发错误,此错误现在也会显示在编辑待办事项删除待办事项旁边,因为所有 3 个操作正在监听相同的内容:state.todo.error

以下是我提出的两个解决方案。任何反馈/批评以及新建议都将受到欢迎。

<小时/>

到目前为止我想到了什么

1:处理每个操作的错误/成功的全局状态缩减器

设置一个全局状态缩减器,用于处理每个操作的错误/成功 - 缩减器上的将由小型专门的子 reducer 每个 Action 独特组成,即:

const status = combineReducers({
  add_todo,     // handles error/success for add_todo
  edit_todo,    // handles error/success for edit_todo
  delete_todo,  // handles error/success for delete_todo
  …
  update_bio,   // handles error/success for update_bio
  etc...
});

然后您可以简单地在组件中监听这些成功/错误消息并按如下方式呈现它们:

function mapStateToProps(state) {
    return { 
        error: state.status.add_todo.error,
        success: state.status.add_todo.success
    }; 
}

{!!this.props.error && <p>{this.props.error}</p>}
{!!this.props.success && <p>{this.props.success}</p>}

等等...

function mapStateToProps(state) {
    return { 
        error: state.status.edit_todo.error,
        success: state.status.edit_todo.success
    }; 
}

{!!this.props.error && <p>{this.props.error}</p>}
{!!this.props.success && <p>{this.props.success}</p>}

这样做的缺点是,它会迫使您为应用程序提供的每个操作创建一个子 reducer ,我不确定这是否是正确的方法?

<小时/>

2:在管理多个操作的每个化简器中使用本地唯一的错误/成功键

即我们可以修改todo reducer 如下:

ADD_TODO_FAILED:
    return {...state, error_add_todo: action.error }

EDIT_TODO_FAILED:
    return {...state, error_edit_todo: action.error }

DELETE_TODO_FAILED:
    return {...state, error_delete_todo: action.error }

然后您可以简单地在组件中监听这些成功/错误消息并按如下方式呈现它们:

function mapStateToProps(state) {
    return { 
        error: state.todo.error_add_todo,
        success: state.todo.success_add_todo
    }; 
}

{!!this.props.error && <p>{this.props.error}</p>}
{!!this.props.success && <p>{this.props.success}</p>}

等等...

function mapStateToProps(state) {
    return { 
        error: state.todo.error_edit_todo,
        success: state.todo.success_edit_todo
    }; 
}

{!!this.props.error && <p>{this.props.error}</p>}
{!!this.props.success && <p>{this.props.success}</p>}

这样做的缺点是,您必须确保给定 reducer 内的每个错误/成功 都是本地唯一的 在该 reducer 内部。

而且它还会使引用 stateMapToProps 中的 keys 更加详细,而不是说 state.todo.error 你必须使用您提供的特定名称来引用该错误

问题

所以我的问题是,基于上述所有内容,我是否完全错过了上述观察中方程式中的某些内容,或者我的观察是否正确,在这种情况下,实现此预期结果的标准方法是什么?

我提出的两个解决方案对于现实世界的应用程序来说是合法的还是太天真了?

非常感谢!

最佳答案

1.

您的第一个选项是有问题的,因为您的每个子 reducer 都无法访问全局状态(待办事项列表)。我想知道您如何对每个子 reducer 进行编码...

2.

你的第二个选择相对较好。但是,它显示了一个常见的危险信号:当您开始命名诸如 state.todo.error_add_todostate.todo.error_edit_todo 之类的变量时,您通常应该使用对象来代替,以 state.todo.error.add_todo 结束。

实际上,我什至会更进一步,将错误成功分组到状态中。

这意味着您将 reshape 您的状态以具有以下形状:

{
  todos:[{...todo1}, {...todo2}, ...todos]
  status:{
    add_todo: {success: true, error: false, message: "yay"}
    remove_todo: {success: false, error: true, message: "nooo"}
  }
}

所以这就是我修复你的代码的方式。然而,这对我来说似乎有点矫枉过正,因为这种状态形状允许您表示并存储来自不同 reducer 的同时错误的任何组合,这对于向用户显示来说并不简单。

在错误显示的情况下,很少需要这种精度,而且通常情况下,当操作失败时,您只是强制触发弹出窗口或 toastr 消息。

此外,您可能应该看看 redux-actionsredux-promise-middleware,这就是我处理错误的方式。

关于reactjs - React Redux 处理每个组件特有的错误/成功消息的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47102043/

相关文章:

javascript - 如何在 React JS 中应用动画

javascript - 为什么这些 Jest 不会重置?

javascript - React-Redux - 创建搜索过滤器

reactjs - 在 Redux 中访问中间件中的状态

reactjs - 在 react 路由器 DOM 和 react Bootstrap 中,Nav.Link vs Link vs NavLink 有什么区别?

javascript - 如果定义了所有属性,则将变量设置为 true

jquery - 使用 jQuery 进行 React 组件而不需要 - jest 单元测试

javascript - 如何使用按钮取消选中所有复选框。在子级中输入标签,在父级中输入按钮。 react -表

javascript - 如何在大型规范化 Redux 存储中组织 reducer

javascript - 访问作为对象的 reducer 有效负载的元素