I have FiltersContainer component, where mapStateToProps function returns object with prop, which contains array:
function mapStateToProps(state) {
const { visibilityFilter } = state.todos;
return {
filters: [{
title: 'All',
value: 'SHOW_ALL',
active: visibilityFilter === 'SHOW_ALL',
}, {
title: 'Completed',
value: 'SHOW_COMPLETED',
active: visibilityFilter === 'SHOW_COMPLETED',
}, {
title: 'Active',
value: 'SHOW_ACTIVE',
active: visibilityFilter === 'SHOW_ACTIVE',
}],
};
}
This component is updating everytime state changes, although filters array wasn't changed.
As I understand shallowEqual function does not deeply comparing two objects and will return false this way, therefore Filters component is updating on every state change.
Why lib uses shallow comparing for mapStateToProps function result instead of deepEqual comparing? Or I'm missing something?
Thanks.
Figured out, the answer is in redux docs.
@1ven This is caused because of referential inequality. You always create new instance of Array therefore shallowEqual consider those two arrays different even the structure is same.
But the problem is deeper - you absolutely don't have to return whole filter structures from mapStateToProps as they seem to be constant. Instead, just have this config statically on module level. And from store, expose only activeFilter property. then you can have comparison like activeFilter === 'SHOW_ACTIVE' in render() method.
Most helpful comment
@1ven This is caused because of referential inequality. You always create new instance of
ArraythereforeshallowEqualconsider those two arrays different even the structure is same.But the problem is deeper - you absolutely don't have to return whole filter structures from
mapStateToPropsas they seem to be constant. Instead, just have this config statically on module level. And from store, expose onlyactiveFilterproperty. then you can have comparison likeactiveFilter === 'SHOW_ACTIVE'in render() method.