0

I started using reselect in my React Native project. I was looking for a way to work with derived data in a redux application that works with large sets of Contacts.

I have a problem with sorting. My main contact list sorts by a numeric field named "delta":

const contactsSelector = state => state.contacts

const sortedContactsSelector = createSelector(
    contactsSelector,
    contacts => contacts.sort(function (a, b) {return a.delta - b.delta})
)

const mapStateToProps = (state, ownProps) => {
    return {
        contacts: sortedContactsSelector(state)
    }
}

It works.

However when I present a modal with a list that is sorted by the contact's name:

const contactsSelector = state => state.contacts

const sortedContactsSelector = createSelector(
    contactsSelector,
    contacts => contacts.sort(function (a, b) {
        if (a.name < b.name)
            return -1;
        if (a.name > b.name)
            return 1;
        return 0;
    })
)

const mapStateToProps = (state, ownProps) => {

    return {
        contacts: sortedContactsSelector(state)
    }
}

And closes the modal - the original main contact screen is sorted by name (as the modal).

Any way around this?

Is the best practice here is cloning:

const contactsSelector = state => state.contacts

const sortedContactsSelector = createSelector(
    contactsSelector,
    contacts => clone(contacts).sort(function (a, b) {
        if (a.name < b.name)
            return -1;
        if (a.name > b.name)
            return 1;
        return 0;
    })
)
Guy
  • 12,488
  • 16
  • 79
  • 119

1 Answers1

1

Your stepped into a state mutation issue caused by Array.prototype.sort() that mutates the original array.

For what I see, your selector gets the contact array directly from the state, mutates it and pass it to you component, causing the unexpected behaviour in your lists and in any other component connected to the selector.

So yes, as you state, you should clone your array every time. And never mutate (of course) or update your state in your selectors. Selectors should be read-only.

Update

reselect will help you caching the resulting array since the original state.contacts remains untouched.

Andrea Carraro
  • 9,731
  • 5
  • 33
  • 57