Повторно выберите проблему createSelector

Пытаясь использовать Rede's Reselect lib, вот так:

// selectors.js
import { createSelector } from "reselect";

const loggedIn = state => {
  return state.language.loggedIn;
};

export const loggedInSelector = createSelector(loggedIn);

И использование так:

import React from "react";
import { connect } from "react-redux";
import { Text, View } from "react-native";
import { loggedInSelector } from "./../lib/selectors/language";

const Foo = ({ loggedIn }) => {
  return (
    <View>
      <Text>Foo - {loggedIn ? "logged in" : "not logged in"}</Text>
    </View>
  );
};

export default connect(state => {
  console.log(state);
  const loggedIn = loggedInSelector(state);
  return {
    loggedIn
  };
})(Foo);

Результатом console.log(state)является:

language: {
  loggedIn: false
}

Тем не менее, я получаю Type Error: createSelector. Может ли кто-нибудь увидеть, где я ошибаюсь в этом, на мой взгляд, достаточно простой вариант использования Reselect?

javascript,reactjs,react-native,redux,reselect,

0

Ответов: 2


0

Оказывается, мне не хватало (казалось бы, обязательного) второго параметра export const loggedInSelector = createSelector(loggedIn, l => l);:

const getLoggedIn = state => state.language.loggedIn export const getloggedInMemoized = createSelector(loggedIn, i => i)


0

Как вы указали в своем собственном ответе, вам не хватает функции преобразования.

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?

  1. Каждый раз, когда вы комбинируете результат двух или более селекторов , поскольку синтаксис createSelectorдействительно подходит для создания этих селекторов. например.

    const taxSelector = createSelector(
      subtotalSelector,
      taxPercentSelector,
      (subtotal, taxPercent) => subtotal * (taxPercent / 100)
    )
  2. Каждый раз, когда селектор делает что-то дорогостоящее . createSelectorбудет гарантировать, что функция преобразования вызывается только в том случае, если результат по меньшей мере одного из селекторов ввода изменился.

  3. И это тонкая, но ключевая причина, на мой взгляд. Когда возвращаемое значение селектора является 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увидит, что ничего не изменилось и что ему не нужно повторно отображать компонент ??.

JavaScript, reactjs, реагируют родной, перевождь, повторно,
Похожие вопросы
Яндекс.Метрика