Let's say we have an immutable object that is created using Facebook's great Immutable.js. I want to compare two lists that were produced using .map
or .filter
out of single source and make sure they are equal. It seems to me, that when using map/filter you are creating a new object that has nothing to do with a previous object. How can I make triple equality ===
work? Does it make sense at all?
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?
You can play with it here: http://jsfiddle.net/eo4v1npf/1/
Context
I am building application using React + Redux. My state has one list that contains items, that have attribute selected
:
items: [
{id: 1, selected: true},
{id: 2, selected: false},
{id: 3, selected: false},
{id: 4, selected: true}
]
I want to pass only selected ids to another container, so I tried it using simple 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);
Problem is, if I set additional attributes:
{id: 1, selected: true, note: "The force is strong with this one"}
This causes state to change and SomePlainComponent
to rerender, although the list of selected Ids is exactly the same. How do I make sure pure renderer works?
Edit with some additional info
For react pure rendering I was using mixin from react-pure-render:
export default function shouldPureComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState);
}
As it is not aware of props that could be immutable, they are treated as changed, i.e.
this.props = {
ids: ImmutableList1
}
nextProps = {
ids: ImmutableList2
}
Although both attributes ids
are equal by content, they are completely different objects and do not pass ImmutableList1 === ImmutableList2
test and shouldComponentUpdate
returns true
. @Gavriel correctly pointed that deep equal would help, but that should be the last resort.
Anyway, I'll just apply accepted solution and problem will be solved, thanks guys! ;)