Как вы указали в своем собственном ответе, вам не хватает функции преобразования.
cannot read property 'language' of undefined
cannot read property 'language' of undefined
Ошибка будет относиться к исходному состоянию вашей функции редуктора.
В вашем memoized селекторе функция преобразования - это только функция идентификации, i => i
которая является очень сильным индикатором того, что селектор, который вы передали ( const loggedIn = state => state.language.loggedIn
), не нуждался в замещении. Зачем? Из-за connect
того, react-redux
что внутренне сделайте свою собственную проверку равенства, чтобы убедиться, что компонент только повторно отображается, если изменяется один или несколько реквизитов.
В принципе, ваш первоначальный loggedIn
селектор отлично работает, и нет необходимости в дополнительных накладных расходах createSelector
(хотя и малых).
Когда использовать createSelector
?
-
Каждый раз, когда вы комбинируете результат двух или более селекторов , поскольку синтаксис createSelector
действительно подходит для создания этих селекторов. например.
const taxSelector = createSelector(
subtotalSelector,
taxPercentSelector,
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
)
-
Каждый раз, когда селектор делает что-то дорогостоящее . createSelector
будет гарантировать, что функция преобразования вызывается только в том случае, если результат по меньшей мере одного из селекторов ввода изменился.
-
И это тонкая, но ключевая причина, на мой взгляд. Когда возвращаемое значение селектора является a array
илиobject
. Это очень важно для производительности. connect
Функция react-redux
будет выполнять простую проверку равенства реквизита , предоставляемых увидеть , если необходимо повторно вынесено (дорого , когда он складывает) компонент. например.
const getSaleItems = state => {
const items = getShopItems(state)
return items.filter(i => i.isOnSale)
}
Каждый раз, когда он getSaleItems
вызывается, он возвращает новый массив. Даже если возвращаемый массив getShopItems
не изменился. Это означает, что react-redux
будет повторно отображать компонент, потому что, когда он выполняет проверку неглубокого равенства на реквизитах, при условии, что он увидит, что массив изменился.
С другой стороны, при использовании createSelector
:
const getSaleItems = createSelector(
getShopItems,
items => items.filter(i => i.isOnSale)
}
Если результат getShopItems
не изменился, последовательные вызовы getSaleItems
вернут один и тот же экземпляр массива, потому что результат будет сохранен в памяти. Это означает, что неглубокая проверка равенства react-redux
увидит, что ничего не изменилось и что ему не нужно повторно отображать компонент ??.