Redux: Каков правильный способ фильтрации массива данных в редукторе?

Я хочу отфильтровать массив в поиске SEARCH_TEXT - это действие по изменению что я смущен, так это то, как я возвращаю состояние, когда нажата клавиша удаления, и текст теперь становится пустым. Я полагаю, что могу использовать начальное состояние в инструкции else, но моя склонность - это неправильно? когда я возвращаю только состояние, все готово было обработано в выражении if.

простой пример.

заблаговременно.

const initialState =  ['hello', 'wahhh', 'yo'];

export default function searchSimple(state = initialState, action) {
  switch (action.type) {
    case SEARCH_TEXT:
      if(action.text.length > 0){
        return state.filter(item =>
          item.startsWith(action.text)
        )
      }
      else {
        return state
      }

Ответы

Ответ 1

Всегда помните, что государство является вашим "источником правды". Будьте осторожны с устранением состояния на основе временного фильтра. Как только вы это сделаете, эти предметы исчезли. (Единственный способ вернуть их назад - сбросить ваше состояние в initialState, что может быть не идеальным.)

Лучший подход - сохранить список товаров как есть и просто сохранить текст поиска.

const initialState = {
    searchText: '',
    items: [ 'hello', 'wahhh', 'yo' ]
};

export default function searchSimple(state = initialState, action) {
    switch (action.type) {
        case SEARCH_TEXT:
            return Object.assign({}, state, {
                searchText: action.text
            });
    }
}

Хотя ваше состояние не будет содержать отфильтрованный список, он расскажет вам все, что вам нужно знать, чтобы построить отфильтрованный список.

Предполагая, что вы используете React, ваш "умный компонент" может быть настроен с помощью следующей функции mapStateToProps():

function mapStateToProps(state) {
    const { items, searchText } = state.searchSimple;
    return {
        filteredItems: items.filter((item) => item.startsWith(searchText))
    };
}

Если вам нужен этот отфильтрованный список более чем в одном месте, рассмотрите возможность создания функции "селектор", как показано в примере с корзиной Redux. https://github.com/reactjs/redux/blob/master/examples/shopping-cart/src/reducers/cart.js

Это будет выглядеть примерно так:

export function filteredItems(state) {
    const { items, searchText } = state.searchSimple;
    return items.filter((item) => item.startsWith(searchText));
}

Для более продвинутого подхода к селекторам, проверьте библиотеку перевыбора.

https://github.com/rackt/reselect

Ответ 2

ИМО, правильное место для фильтрации данных не непосредственно в редукторах, а в селекторах.

Из редукционных документов:

Вычисление производных данных

Reselect - это простая библиотека для создания запоминаемых, компонуемых функций селектора. Повторно выбрать селекторы можно использовать для эффективного вычисления производных данных из хранилища Redux.

В настоящее время я использую селекторы для фильтрации и сортировки данных.

  1. Нет повторения данных в состоянии. Вам не нужно хранить копию отфильтрованных элементов.
  2. Одни и те же данные могут использоваться в разных компонентах, каждый из которых, например, использует свой фильтр.
  3. Вы можете комбинировать селектор, применяя множество вычислений данных, используя селектор, который у вас уже есть в приложении.
  4. Если вы все сделаете правильно, ваши селекторы будут чистыми функциями, тогда вы можете легко их проверить.
  5. Используйте один и тот же селектор во многих компонентах.