redux - redux mapStateToProps 的最佳实践?

标签 redux react-redux

据我所知,reducers 改变树的状态,mapStateToProps 转换 UI 的状态树。然而,边界并不明确。例如,考虑“计算派生数据”文档中的示例 ( http://redux.js.org/docs/recipes/ComputingDerivedData.html )。见下文。

我的第一直觉是将可见待办事项的计算放在 reducer 中(而不是 mapStateToProps),也就是说,每当待办事项或可见性过滤器发生变化时,更新已完成或事件的待办事项列表。这有几个优点:

  1. 无需重新选择
  2. 将所有逻辑集中到一处有助于缩短学习曲线(入门时),并且可能还可以使其更容易测试(因为 mapStateToProps 的集成测试更简单,即使不存在)。

另一方面,2) 是主观的。因此,有关 mapStateToProps 的指导会很有帮助。

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_ALL':
      return todos
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
  }  
}

const mapStateToProps = (state) => ({
  todos: getVisibleTodos(state.todos, state.visibilityFilter)
})

const mapDispatchToProps = (dispatch) => ({
  onTodoClick: (id) => dispatch(toggleTodo(id))         
})

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

更新响应@DDS:

To update multiple interrelated states based on one action means that these states can become out of sync... This could mean the visibleTodoList acquires items that don't exist in the original.

如果您指的是多个相互关联的状态 visibilityFiltertodos,那么根据 redux 文档,一种惯用的解决方案是重构状态树,使它们成为一个状态。文档中还提到了其他方法。当然,正如您所提到的,您现在有责任确保始终调用计算派生状态(可见待办事项)的代码。一旦代码库变大,在返回状态之前执行额外转换的自定义的combineReducer(另一个惯用的解决方案)就有意义了。

Note that the code lives in separate files and the execution order of reducers is not guaranteed. Also, reducers don't normally have access to sibling state meaning they cannot derive data from it

请参阅上面我的评论。

The example above may be contrived but the point is that to make the data stable, it's best to have a single source every component can rely on, and this requires the data to be normalized.

是的,这一切都归结为标准化与非标准化状态。我还不相信规范化状态总是是正确的选择……出于同样的原因,NoSQL 数据库有时也是正确的选择。

Reasoning about more complex state [normalized and denormalized state] becomes difficult very quickly. This is why it is better to not put derived data in state.

啊我明白你的意思了。六个月后,我可能看不到 visibleTodos 是派生状态(因此应该被视为只读)。会有意想不到的结果。

最佳答案

注意:这是我根据个人经验得出的两分钱,不一定符合最佳实践。

Redux 状态

这应该被标准化,主要是因为它使写入(插入/更新/删除)易于推理。 规范化 redux 状态意味着您不应该将派生数据存储在 redux 状态中。

派生数据:

我使用react/redux的个人经验(在http://redux.js.org/docs/recipes/ComputingDerivedData.html上的优秀文档出现之前)让我尝试遵循您(OP)正在努力实现的目标:简化编写代码的地方。 在接受规范化原则之后,我开始编写推导或“状态 View ”逻辑的自然位置是在 react 组件的渲染函数中(现在听起来有点难看)。随着代码的发展,通过创建派生函数并将它们保留在 react 组件之外,渲染函数变得更加整洁。

这为使用代码库的人员创建了一个简单的心理模型:

  • redux-state:标准化存储
  • mapStateToProps:仅以一种愚蠢的方式将状态映射到 prop 值
  • ReactComponent:包含“查看”状态的正确部分然后渲染它的所有逻辑。作者认为必要时进行进一步的模块化。

关于redux - redux mapStateToProps 的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40275323/

相关文章:

reactjs - 如何在 Redux 状态存储中的对象内添加新的键/值对?

javascript - CreateAsyncThunk 错误 : Actions must be plain objects. 使用自定义中间件进行异步操作

javascript - 异步操作未及时将数据添加到 Redux 存储导致错误 : Cannot read property 'map' of undefined

javascript - React redux如何使用过滤器比较两个obj数组

javascript - `redux-loop` 和 `connected-react-router` 兼容吗?

redux - 使用 redux-saga yield call 调用外部函数似乎会出现上下文错误

javascript - 在 React 中卸载组件时监听器不会被删除

reactjs - react Redux : Testing mapStateToProps and mapDispatchToProps with Enzyme/Jest

javascript - 如何在 React 中使用循环旋转木马实现平滑过渡

redux - 如何将参数从 sagaMiddleware 传递到 Action 观察器