我是react-redux的新手,我很惊讶地看到一个示例,其中一个函数,在本例中是getVisiblieTodos,在mapStateToProps中调用。这个函数应该在reducer中调用,因为它改变了状态?代码是否打破"良好的形式"为了简洁起见?一般来说这样做可以吗?
我正在查看此link
的代码import { connect } from 'react-redux'
import { toggleTodo } from '../actions'
import TodoList from '../components/TodoList'
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) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
答案 0 :(得分:2)
在redux中,我们希望商店保存应用程序所需的最小数据。从基础数据派生的所有内容都应该动态计算,以防止克隆商店的部分,并且当商店中的某些内容发生变化时需要重新计算所有派生数据。
由于可见待办事项列表不是商店的一部分,而是使用todos
列表和visibilityFilter
计算,因此getVisibleTodos()
不会更改商店的状态。它从这两个属性生成派生的计算数据。
用于从商店获取数据并计算派生数据的函数称为selector。使用选择器,派生数据不是存储的一部分,并在需要时计算。另外,我们可以使用memoized选择器来节省计算开销。
答案 1 :(得分:1)
todos
是基于reducer状态的计算属性,并且不会更改任何状态。
可以转换来自仅由一个组件使用的recuder的属性(它们被称为selectors
)。想象一下,在其他组件中使用todos
,您不希望在一个组件中进行更改,例如过滤并在其他组件中查看。如果是这种情况,可以这样做。
此外,reducer的一个很好的属性是只存储所需的数据。更多状态在应用程序中更复杂,并且计算新状态的开销更大。
答案 2 :(得分:1)
您可能会将getVisibleTodos
视为减速器,因为它包含" switch .. case"阻止或/和因为它有2个参数。但是,这不是一个规则。
redux reducer(根据定义)根据调度的操作更改存储状态,这就是为什么它需要两个参数(存储状态+调度的操作)并且它为没有变异的存储返回新状态。
getVisibleTodos
这是一个辅助函数,它根据字符串(过滤器)过滤数组。
此外,filter
不是redux-action,只是字符串决定要渲染的待办事项。
我可能同意你的看法,这很奇怪,如果我们能够看到整个应用程序(减速器,动作......),我们就可以决定它是否是最佳实践。
答案 3 :(得分:0)
在我看来,一个函数应该按照其名称所说的去做,没什么少,仅此而已。
mapStateToProps()
应该只是这样做,即“映射”,通常不应调用其他函数。