javascript - Redux 减速器参考
问题描述
当我们触发一个动作时,redux 的状态会发生什么?
- 我们有 redux 的当前状态
- 我们称之为行动
- 每个 reducer 在包含正确 actionType 的 switch 中查找自己的 case
- 每个reducer都返回状态-即使在默认情况下,每个reducer是否都返回对状态的新引用
return state
?
如果它在减速器中返回,状态实际上会发生什么?它使用某种reduce函数来比较状态并调用重新渲染,然后返回新的引用并做出反应,然后比较是否有任何变化并调用重新渲染?
解决方案
您在这里谈论的是一个减速器,它是通过将多个“切片”减速器组合而成的combineReducers
。像这样的东西:
const rootReducer = combineReducers({
users: usersReducer,
posts: postsReducer,
})
假设我们dispatch
是一个带有类型的动作ADD_USER
——这是usersReducer
会响应但不会响应的东西postsReducer
。
每个reducer都返回状态-即使在默认情况下,每个reducer是否都返回对状态的新引用
return state
?
postsReducer
不关心这个动作,只会return state
. 这是对现有对象的引用。所以state.posts
是相同的。
将usersReducer
为其状态创建并返回一个新对象。state.users
对内存中与以前不同的对象的引用也是如此。如果其中嵌套了其他数组或对象,那么state.user
这些对象将是相同的引用,除非我们在 reducer 中替换它们。因此,您正在处理一个“浅拷贝”,其中state.users
是一个新对象,但一个深度嵌套的对象state.users.byId[5]
可能与以前完全相同。
你可能认为根在处理时总是一个新的对象引用,state
因为它combineReducers
本质上是这样做的:
const rootReducer = (state, action) => ({
users: usersReducer(state, action),
posts: postsReducer(state, action),
});
但实际实现更复杂,它涉及一些检查以防止不必要的对象创建。如果每个单独的 reducer 都只是使用default: return state;
,则返回原始state
对象。
以下是该combineReducers
功能的工作原理:
- 它有一个
boolean
标志属性hasChanged
,最初是false
. - 它创建 a
nextState
最初是一个空对象(很明显这是一个新对象)。 - 它遍历每个单独的属性 reducer,并
nextState
使用该属性的更新状态更新 。如果属性 reducer 返回一个新状态,则hasChanged
变为true
. - 如果在调用所有属性 reducer 之后
hasChanged
仍然是,则它忽略并返回原始变量。false
nextState
state
- 否则它返回
nextState
.
当使用类似的 React 绑定时useSelector
,它(默认情况下)对返回的值进行严格的相等检查。因此,如果您返回一个新对象,它是前一个对象的精确副本,它将触发重新渲染,因为该对象是不同的引用。reselect
这就是为什么如果涉及到通过array.map
,等创建对象时,使用诸如记忆选择器之类的东西很重要array.filter
。否则每次都会有一个新的对象引用。 useSelector
还支持自定义相等检查,以便您可以控制何时发生重新渲染。
推荐阅读
- c++ - (BOOST) 迭代过滤出图的边
- javascript - 使用 .includes 查找数字中的数字是否与不同数字中的相同数字(例如 21 和 12)
- django - 在 DRF 中,如何正确显示一个模型内部的相关名称字段?
- azure - Azure Java SDK - 无法添加资源锁
- arrays - 等待循环完成,DispatchGroup 使用 Swift 从 firebase 获取数据
- python-3.x - 在索引时在熊猫对象上使用拆分会给出关键错误
- javascript - 我只想从我自己的组件中的他自己的按钮显示下拉菜单,该组件已在 React Native 中使用数组映射方法循环
- php - 如何在不修改预先存在和标签的情况下用超链接替换特定文本?
- c# - 通过单个元素在集合中通过 wpf datagrid 更新属性
- javascript - 如何小写一个特定的字母?