Redux Reselect - селектор с вводом аргумента пересчитывает - PullRequest
1 голос
/ 26 мая 2019

У меня есть следующий селектор:

const getAllAddresses = (withStartEnd) => 
    createSelector(
        [getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
        (all, startAddress, endAddress) => {
            if (!withStartEnd) return [...Object.values(all)];
            return [startAddress, ...Object.values(all), endAddress];
        }
    );

Я заметил, что селектор пересчитывает каждый раз, событие, когда all, startAddress и endAddress не меняются. Если я уберу вход для функции селектора, примерно так:

const getAllAddresses = (
    createSelector(
        [getAllAddressesSelector, getStartAddressSelector, getEndAddressSelector],
        (all, startAddress, endAddress) => {
            return [startAddress, ...Object.values(all), endAddress];
        }
    )
);

Тогда все работает как положено, и селектор не пересчитывает при каждом вызове. Похоже, я что-то упустил в концепции селектора. Любая помощь будет высоко ценится.

1 Ответ

2 голосов
/ 11 июня 2019

Обновление:

Пожалуйста, обратитесь к Как мне создать селектор, который принимает аргумент?

Короче говоря, способ, которым вы это сделали, будет работать, только если вы передадите статические аргументы и создадите фабричную функцию за пределами mapStateToProps. Для динамических аргументов это более сложно, и, пожалуйста, следуйте ресурсу, который я уже упоминал выше.

Причина, по которой ваш селектор пересчитывается каждый раз при вызове mapStateToProps, заключается в том, что вызов getAllAddresses создаст новый экземпляр createSelector, и памятка не будет работать.


Оригинальный ответ:

Короче говоря, reselect определяет изменения селектора входа на основе проверки личности ===.

Поэтому, если ваши входные селекторы всегда создают и возвращают новый объект или массив, ваш селектор будет пересчитываться каждый раз.

Для устранения проблем с перерасчетом:

  1. Убедитесь, что ваши входные селекторы всегда возвращают ссылку, а не новый объект / массив.
  2. Или, если новый объект / массив является правильным возвращаемым значением, тогда вам нужно настроить равенство равенства для defaultMemoize

Из reselect документов:

Почему мой селектор пересчитывает, когда состояние ввода остается прежним? (перейдите по ссылке, есть отличные примеры)

Убедитесь, что функция напоминания совместима с функцией обновления состояния (т. Е. Редуктор, если вы используете Redux). Например, селектор, созданный с помощью createSelector, который неожиданно перевычисляет, может получать новый объект при каждом обновлении, изменились ли содержащиеся в нем значения или нет. createSelector использует проверку идентичности (===) для определения того, что вход изменился, поэтому возвращение нового объекта при каждом обновлении означает, что селектор будет повторно вычисляться при каждом обновлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...