Reactjs 浅道具比较如何适用于连接的零部件?
根据redux的文档,reducer总是提供状态的新副本。 在连接的组件中,react-redux对Reactjs 浅道具比较如何适用于连接的零部件?,reactjs,react-native,redux,react-redux,Reactjs,React Native,Redux,React Redux,根据redux的文档,reducer总是提供状态的新副本。 在连接的组件中,react-redux对mapStateToProps中提到的属性(旧的和新的道具)进行了粗略的比较 我的困惑是,因为redux总是提供状态的新副本,所以react redux进行的浅层比较应该总是给出false,组件应该总是重新加载。但事实并非如此 有人能解释一下我遗漏了什么吗 我认为mapStateToProp中读取的所有属性都是对象。我们都同意,如果存储状态相同,mapStateToProps将不会运行。因此,re
mapStateToProps
中提到的属性(旧的和新的道具)进行了粗略的比较
我的困惑是,因为redux总是提供状态的新副本,所以react redux进行的浅层比较应该总是给出false,组件应该总是重新加载。但事实并非如此
有人能解释一下我遗漏了什么吗
我认为mapStateToProp中读取的所有属性都是对象。我们都同意,如果存储状态相同,
mapStateToProps
将不会运行。因此,redux文档是:
connect生成的包装器组件订阅Redux
商店。每次调度操作时,它都会调用store.getState()
并检查是否lastState===currentState
。如果两个国家
引用的值相同,则不会重新运行
MapStateTops
函数,因为它假定
商店状态也没有改变
答案
可以描述您的情况,因为您可能会意外地直接改变您的状态
既然您使用的是“combineReducers”(这很好),那么还有一个“问题”:
combineReducers
实用程序函数尝试优化状态更新。如果
没有一个切片还原器返回新值,然后是组合还原器
返回旧的状态对象,而不是新的状态对象。这意味着
减速器中的突变可能导致根状态对象不可用
已更新,因此UI不会重新呈现
只要子减速器没有发生变异,它就保持引用相同,无论根状态是否为新对象,因此connect对减速器该部分的浅层比较总是返回true。因此,不会对依赖于该特定状态的组件进行重新渲染
const subReducerState = { innerProp: 3 };
const prevRootState = { subReducerState: subReducerState };
const nextRootState = { subReducerState: subReducerState };
prevRootState.subReducerState === nextRootState.subReducerState // returns true
Redux并不总是提供新副本。程序员的工作是通过以下几点来确保它在真正应该的时候运行:
- 减速机是否确实更改了任何状态,并且不可变地返回了一个新对象(见下文)?否则,redux reducer将只返回旧对象,因此不会重新渲染。您可能错误地返回了原始数组
- 使用诸如
或Object.assign()
之类的函数复制对象, 和数组函数,如\uux.extend()
和slice()
concat()
- ES6中的数组扩展运算符,以及类似的对象扩展运算符 建议使用未来版本的JavaScript
- 将不可变更新逻辑包装成更简单函数的实用程序库
- 类似地,如果您使用的是
,请确保组成组合减速器的所有减速器都实际返回一个新对象combineReducer()
- 你在旧州做什么变异?如果您这样做,那么这些将不会导致新对象自行返回。您需要返回一个新的对象,并如上所述应用所需的更改。切勿对旧状态进行变异,因为它将在以后与新状态进行比较时使用
- 如果您有嵌套对象(例如:
),并且如果您在减速器中更改了嵌套对象,则需要为其返回新对象,并为其所有父对象返回。例如:main.subsection.nanopart
中的任何更改都应该为nanopart
、nanopart
和子部分
返回新对象main
- 如果您的reducer返回未处理操作的旧状态(通常是这种情况),则您可能没有正确处理reducer中的操作,并且导致未处理操作的旧对象从
分支返回默认
- 减速器应该是纯的:给定输入,输出应该是相同的(确定性纯计算)。因此,您不应该使用非确定性元素,例如利用
,Date.now()
。此外,您不应该导致API调用或路由传输等副作用。将reducer保持为在旧状态上进行的纯计算,以将新状态作为新对象返回。读这里Math.random()
- 用
修饰的视图调用并只考虑更改的道具。如果视图依赖于全局状态或其父组件(),则不会根据全局状态或父组件中的更改重新渲染组件。这可能是由您的第三方库引起的。您需要通过道具传递更改,或者指出您的组件不是纯组件(不建议,因为它会变慢) 导出默认连接( MapStateTops, 无效的 无效的 { 纯:假 } )(YourApp)connect()
- 还要确保
mapDispatchToProps
connect()
或使用bindActionCreators()
方法的参数,或
您可以手动调用dispatch()
。只是打电话给你的朋友
MyActionCreators.addTodo()
函数无法工作,因为它只返回
一个动作,但不发送它
查看以下故障排除页面,这些页面详细解释了这些问题:
您能分享您的
MapStateTrops
?这在很大程度上取决于它。可能您正在使用类似于reselect
(哪个处理缓存)?const-mapStateToProps=state=>({response:state.simpleReducer.result,});“result”是一个数组,我没有使用reselect。这是一个相当基本的redux应用程序。我的困惑是,在这个应用程序中,我正在改变其他的标准。