reselect: v3 breaks my app
I’m not sure what’s happening. I (ab)use reselect to calculate derived values from component props and state, by using my React element as state, not simply the redux store.
Example:
class Table extends React.Component {
getColumns = createSelector(
[
() => this.props.columns,
() => this.state.show,
],
(origCols = {}, show) => {
// calculate the column object to give to the table component
}
)
render() {
const allCols = this.getColumns()
// …
}
}
I am passing extra data (via deep mutation) through the columns object to the Table
component, and to make sure the columns are recalculated, I copy the column object into a new one. That works fine with v2.5.4, but in v3 the selector doesn’t update.
Is there a deeper comparison of the inputselectors being made in v3? The columns
object changes but its direct descendants don’t.
I suppose I should just man up and rewrite that code so the mutations are an extra input, but it would be good if this is noted as a possibly breaking change.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 16 (4 by maintainers)
So, any thoughts on this in the meantime?
For me, the solution would be to only check the state for equality if the state is not
undefined
. Then it will run my bound input selectors and everything will work as it should. This is entirely backwards compatible.More generically, I think adding an option parameter to
createSelector
, or making a differentcreateNonPureSelector
would provide an easy upgrade path for people that are relying on the unintended v2 behavior.I also got bit by this.
Solved it with the following workaround that should be fine unless your input functions are using the argument count or otherwise can’t handle an extra argument
@wmertens if you’re looking for a solution in the meantime, this should work. Obviously doesn’t work for use in
@connect()
, but is a convenient way to avoid the===
check for your use case.I think @johnhaley81 is right in that Reselect was intended to be used with immutable data. The ‘impure’ use case was accidentally supported. I am trying to see if there is a nice way to have the optimization as the default, but allow the old behavior too. Suggestions welcome.