Представим, что у нас есть приложение React / Redux для бронирования мест на рейс. Каждое сиденье - это объект, который выглядит примерно так:

{id: 1, seatClass: "business", cost: 300, availability: "available"} 

Все места хранятся в нашем состоянии Redux: state.seats.allSeats, которое представляет собой массив объектов сидений. Когда пользователь бронирует место на рейс, идентификатор этого места сохраняется в state.auth.user.reservation. Так что, если бы мы хотели показать детали бронирования места для нашего текущего пользователя, вошедшего в систему? Мы могли бы сделать что-то подобное в mapStateToProps:

const mapStateToProps = (state) => {
  state.seats.allSeats.find(seat => {
    return seat.id === state.auth.user.reservation
  }
}

Это полностью сработает, но использование такой логики в mapStateToProps считается плохой практикой. Если бы нам нужно было снова отобразить эту информацию, нам пришлось бы скопировать и вставить этот код, и это совсем не СУХОЙ. Итак, куда мы должны его положить? В функции селектора.

Вам может быть интересно, что такое селекторная функция на данный момент - отличный вопрос. Селекторная функция вычисляет производные данные и позволяет Redux сохранять минимально возможное состояние. Другими словами, он использует логику вычислений для хранения только той части состояния, которая вам нужна. Если вы все еще очень запутались, я полностью понимаю. Так было и со мной. По сути, селекторы берут одну или несколько частей состояния Redux, производят какие-то вычисления, а затем возвращают вычисленную часть состояния - так же, как это делает наш mapStateToProps выше. Но вместо этого мы удаляем логику из mapStateToProps в отдельную функцию - наш селектор. Это выглядит почти идентично нашей функции сверху:

const selectUserSeat = (state) => {
  state.seats.allSeats.find(seat => {
    return seat.id === state.auth.user.reservation
  }
}

Здорово! Теперь, если нам снова понадобится информация о месте пользователя, мы можем просто передать этот селектор в mapStateToProps.

const mapStateToProps = (state) => {
 return {reservedUserSeat: selectUserSeat(state)}
}

Оптимизация селекторов с помощью повторного выбора

Важно отметить, что функции селектора пересчитывают данные при каждом вызове. Если вы читали мои последние блоги, возможно, вы знаете, как мы можем этого избежать - мемоизация. Если вам нужно вспомнить, что такое мемоизация, ознакомьтесь с моим блогом, указанным ниже:



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

Давайте рассмотрим простой пример использования Reselect. Мы можем установить его, используя простой yarn add reselect или npm install reselect. Затем мы используем функцию createSelector Reselect, которая принимает части состояния, которые будут использоваться в вычислениях, в качестве первого аргумента (ов) (если есть 2 отдельных части состояния, которые нас интересуют, они будут первыми двумя аргументами. функции), а последним аргументом будет функция, которая выполняет вычисление с использованием этих частей состояния и возвращает производные данные. Обещаю, это не так сложно, как кажется. Давайте посмотрим на это здесь:

// First, we grab the pieces of state we're concerned with
const seatList = (state) => state.seats.allSeats
const reservedSeat = (state) => state.auth.user.reservation
// Then, we plug them into the createSelector function as the first // arguments. The last argument will be a function that makes our  // calculation and spits out the data we want.
const selectedUserSeat = createSelector(
seatList,
reservedSeat,
(allSeats, reservation) => {
  return allSeats.find(seat => seat.id === reservation)
}
)

Теперь ваша селекторная функция будет пересчитывать только при изменении state.seats.allSeats или state.auth.user.reservation. В противном случае он просто вернет запомненное значение!

Теперь, когда вы знаете основы функций селектора, вы готовы повысить уровень своей организации и оптимизации в приложении Redux. Если вы хотите узнать больше о селекторах в целом или глубже изучить то, что предлагает Reselect, я привел ссылки на некоторые ресурсы ниже, которые были для меня особенно полезны. Удачи!