Как я могу фильтровать данные, используя Redux, но сохраняя старое состояние? - PullRequest
0 голосов
/ 22 февраля 2019

Я работаю над поиском в Redux, но у меня возникли некоторые проблемы.

Вот действия, связанные с поиском:

export const passengersDataAction = passengersData => ({
  type: ActionTypes.PASSENGERS_DATA,
  // This is the array of objects that I need to search through
  payload: { passengersData }, 
});

export const searchParamAction = searchParam => ({
  type: ActionTypes.SEARCH_PARAM,
  // This is the param that I need to send to passengersData
  // in order to get a new array of objects based on the searchParam
  payload: { searchParam },
});

Редукторы:

const initialState = {
  passengersData: [],
  searchParam: '',
};

const handlers = {
  [ActionTypes.PASSENGERS_DATA](state, action) {
    return {
      ...state,
      passengersData: action.payload.passengersData,
    };
  },

  [ActionTypes.SEARCH_PARAM](state, action) {
    return {
      ...state,
      searchParam: action.payload.searchParam,
    };
  },
};

Кстати, так выглядит массив объектов:

[
 {
  "id": 3,
  "name": "Marcos Alonso",
  "address": "Sabana",
  "phone": "712321222",
  "pickup": 0,
  "cardinalpoint": "N",
  "latitude": "9.93683450",
  "longitude": "-84.10991830",
  "timestamp": "2019-02-19 21:23:46",
  "dropofftimestamp": null,
  "pickuptimestamp": null,
  "deleted": null,
  "driver": 1
 },
 ...
]

Это то, что я пытаюсь заставить его работать:

   [ActionTypes.SEARCH_PARAM](state, action) {
    //In filter you can add your own logic to get the data
    const searchedData = state.passengersData.filter((passenger) => passenger.name === action.payload.searchParam);

       return {
         ...state,
         passengersData: searchedData,
         searchParam: action.payload.searchParam,
       };
    },

Но с помощью приведенного выше кода он заменяет passesngerData на 'selectedData'.Мне нужно сохранить исходный passengerData, поэтому, я думаю, я могу создать новое состояние в хранилище и восстановить его из редуктора.У меня вопрос, как я могу это сделать?Каждый раз, когда я что-то печатаю во входных данных, весь массив passengersData исчезает, и поиск ничего не возвращает.

Чего мне не хватает?

РЕДАКТИРОВАТЬ

Я собираюсь добавить код, касающийся компонентов, которые обрабатывают функции поиска:

// imports
import { searchParamAction } from '../../screens/HomeScreen/actions/homeScreen';

class AllPassengersList extends Component {
  render() {
    const {
      searchParamActionHandler,
      searchParam,
    } = this.props;
    return (
      <View>
          <View>
            <TextInput
              onChangeText={text => searchParamActionHandler(text)}
              value={searchParam}
              placeholder="Search..."
            />
          </View>
        <Text>{searchParam}</Text>
        <PassengerCardBasedOnRoute searchParam={searchParam} />
      </View>
    );
  }
}

AllPassengersList.propTypes = {
  passengersData: PropTypes.oneOfType([PropTypes.array]).isRequired,
  searchParam: PropTypes.oneOfType([PropTypes.string]).isRequired,
  searchParamActionHandler: PropTypes.oneOfType([PropTypes.func]).isRequired,
};

export default compose(
  connect(
    store => ({
      navigationStore: store.homeScreen.navigation,
      searchParam: store.homeScreen.searchParam,
      passengersData: store.homeScreen.passengersData,
    }),
    dispatch => ({
      searchParamActionHandler: value => {
        dispatch(searchParamAction(value));
      },
    }),
  ),
)(AllPassengersList);

Компонент выше - это тот, который содержит ввод текста поиска.Ниже приведен тот, где я рендерину массив объектов, которые мне нужно отфильтровать:

import { View } from 'react-native';
import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import PassengersInfo from './PassengerInfo';

import { popupsModalsAction } from '../PopupsModals/actions/popupsModals';

const PassengerCardBasedOnRoute = ({
  navigationStore,
  passengersData,
  popupsModalsActionHandler,
  searchParam,
}) => {
  return (
      <View>
        {passengersData.map(info => (
            <PassengersInfo
              key={info.id}
              id={info.id}
              searchParam={searchParam}
              cardinalpoint={info.cardinalpoint}
              name={info.name}
              address={info.address}
              datetime={info.timestamp}
            />
          ))}
      </View>
  );
};

PassengerCardBasedOnRoute.propTypes = {
  passengersData: PropTypes.oneOfType([PropTypes.array]).isRequired,
  searchParam: PropTypes.oneOfType([PropTypes.string]).isRequired,
};

export default compose(
  connect(
    store => ({
      passengersData: store.homeScreen.passengersData,
      searchParam: store.homeScreen.searchParam,
    }),
  ),
)(PassengerCardBasedOnRoute);

Так что passengersData - это массив, который обрабатывает нужные мне данные.

1 Ответ

0 голосов
/ 22 февраля 2019

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

const filterSelector = (state, props) => {
    return state.passengersData.filter((passenger) => passenger.name === state.searchParam);
}

const mapStateToProps = (state, props) => {
   const searchData = filterSelector(state, props);
   return {
       searchData
   }
}

, а значение редуктора будет просто

[ActionTypes.SEARCH_PARAM](state, action) {
       return {
         ...state,
         searchParam: action.payload.searchParam,
       };
    }

РЕДАКТИРОВАТЬ: обновление кода с примером

// imports
import { searchParamAction } from '../../screens/HomeScreen/actions/homeScreen';

class AllPassengersList extends Component {
  render() {
    const {
      searchParamActionHandler,
      searchParam,
    } = this.props;
    return (
      <View>
          <View>
            <TextInput
              onChangeText={text => searchParamActionHandler(text)}
              value={searchParam}
              placeholder="Search..."
            />
          </View>
        <Text>{searchParam}</Text>
        <PassengerCardBasedOnRoute searchParam={searchParam} />
      </View>
    );
  }
}

AllPassengersList.propTypes = {
  passengersData: PropTypes.oneOfType([PropTypes.array]).isRequired,
  searchParam: PropTypes.oneOfType([PropTypes.string]).isRequired,
  searchParamActionHandler: PropTypes.oneOfType([PropTypes.func]).isRequired,
};

const filterSelector = (passengersData, searchParam) => {
     return passengersData.filter((passenger) => searchParams == '' || passenger.name === searchParam);
}

const mapStateToProps = store => ({
      navigationStore: store.homeScreen.navigation,
      searchParam: store.homeScreen.searchParam,
      passengersData: filterSelector(state.homeScreen.passengersData, state.homeScreen.searchParam),
}),
export default compose(
  connect(

    dispatch => ({
      searchParamActionHandler: value => {
        dispatch(searchParamAction(value));
      },
    }),
  ),
)(AllPassengersList);
,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...