两个不可变的列表 - 如何使三重平等工作
Two immutable lists - how to make triple equality work?
假设我们有一个不可变的对象,它是使用Facebook伟大的Immutable.js创建的。我想比较使用单一来源的.map
或.filter
生成的两个列表,并确保它们相等。在我看来,使用map/filter时,您正在创建一个与先前对象无关的新对象。如何使三重平等===
起作用?这完全有意义吗?
var list = Immutable.List([ 1, 2, 3 ]);
var list1 = list.map(function(item) { return item; })
var list2 = list.map(function(item) { return item; })
console.log("LIST1 =", list1.toJS()) // [1, 2, 3]
console.log("LIST2 =", list2.toJS()) // [1, 2, 3]
console.log("EQUAL ===?", list1===list2); // false! Why? How?
你可以在这里玩它:http://jsfiddle.net/eo4v1npf/1/
上下文
我正在使用 React + Redux 构建应用程序。我的州有一个列表,其中包含具有属性selected
的项目:
items: [
{id: 1, selected: true},
{id: 2, selected: false},
{id: 3, selected: false},
{id: 4, selected: true}
]
我只想将选定的 id 传递给另一个容器,所以我尝试使用简单的 connect
function getSelectedIds(items) {
return items
.filter((item) => item.get("selected"))
.map((item) => item.get("id"));
}
export default connect(
(state: any) => ({
ids: getSelectedIds(state.get("items"))
})
)(SomePlainComponent);
问题是,如果我设置其他属性:
{id: 1, selected: true, note: "The force is strong with this one"}
这会导致状态更改并重新呈现SomePlainComponent
,尽管所选 Id 的列表完全相同。如何确保纯渲染器正常工作?
使用一些附加信息进行编辑
对于反应纯渲染,我使用了来自反应纯渲染的mixin:
export default function shouldPureComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState);
}
由于它不知道可能是不可变的道具,因此它们被视为已更改,即
this.props = {
ids: ImmutableList1
}
nextProps = {
ids: ImmutableList2
}
尽管这两个属性ids
在内容上是相等的,但它们是完全不同的对象,没有通过ImmutableList1 === ImmutableList2
测试,shouldComponentUpdate
返回true
。 @Gavriel正确地指出深度平等会有所帮助,但这应该是最后的手段。
无论如何,我只会应用接受的解决方案,问题就会得到解决,谢谢大家! ;)
你永远不可能有不可变结构的严格相等,因为不可变.js对象本质上是唯一的。
您可以使用 .is
函数,该函数接受两个不可变的对象并比较其中的值。这是有效的,因为不可变结构实现了equals
和hashCode
。
var map1 = Immutable.Map({a:1, b:1, c:1});
var map2 = Immutable.Map({a:1, b:1, c:1});
console.log(Immutable.is(map1, map2));
// true
如果你想保持你的组件纯净并使用===
那么你也可以去规范化你的 Redux 状态,并将 selectedId 作为属性存储在存储中。 仅当发生添加/删除选定项或切换项选择的操作时,才更新此列表,而不在更新项的其他任意属性时更新此列表。
- CreateJS:无法使tweening工作
- 它们是github上Splitview ZIP中使插件工作所需的文件
- Jquery只有在加载图像后才能使fadeIn工作
- 低级反应动画 API 无法使其工作
- 在使 dojo 1.7.2 工作时遇到问题
- 如何在Microsoft IIS上使用反应路由器(createBrowserHistory)使路由工作
- 如何使三.js全屏
- Jasmine spyOn:当传递间谍函数引用时如何使其工作
- 我想在js文件中包含$(document).keydown(function (e) {,但我无法使其工作
- 将结果从.html(或innerHtml)输入到inArray并使其工作
- 我在哪里放置此JS代码以使其工作
- 当我将变量附加到 URL 时,如何使 .load 工作
- 两个不可变的列表 - 如何使三重平等工作
- 如何使它工作加载并一起准备好
- Javascript:代码片段,无法使其工作(设置和读取cookie)
- 我可以't使clearInterval工作:/
- 基于字符串搜索的简单jquery查找和显示无法使其工作
- 数组错误如何使其工作
- Javascript:XMLHttpRecust:如何使其工作
- 由于回调结构中可能存在错误,无法使超时工作