1
votes

Comment filtrer les données par catégorie à l'aide d'une action et d'un réducteur dans redux?

Je suis en train de créer un filtre, dans lequel les utilisateurs peuvent filtrer les données selon le type de catégorie qu'ils souhaitent, par exemple, les restaurants, les bars, les cafés, etc. L'utilisateur utilise le filtre, en sélectionnant si la catégorie est vraie de false (c'est-à-dire si cette catégorie spécifique est affichée ou non), qui est ensuite envoyée à mon action et à mon réducteur. Comment définiriez-vous le réducteur pour filtrer les données, de sorte que seules les catégories qui sont vraies apparaissent?

Voici mon fichier filter.js (avec shop et food étant soit vrai soit faux):

myRecommendations: [
    {
      id: '1',
      name: 'Yes Food',
      type: 'food'
    },
            {
      id: '2',
      name: 'Yes Shop',
      type: 'shop'
    },
]

Voici mon fichier action.js:

export const reducer = (state = INITIAL_STATE, action) => {
    switch (action.type) {
    case FILTER_RECOMMENDATIONS_BY_TYPE:
        return {
            ...state,
                myRecommendations: state.myRecommendations.filter(
            item => item.type === action.payload
            )
        };
};

Voici mon fichier reducer.js:

export const filterRecommendations = ({ shop, food}) => {
    return {
        type: FILTER_RECOMMENDATIONS_BY_TYPE,
        payload: { shop, food }
    };
};


8 commentaires

Vous ne devez pas utiliser de réducteurs pour obtenir des valeurs. Les réducteurs sont utiles pour mettre à jour l'état. Utilisez plutôt des sélecteurs.


Pouvez-vous montrer / créer un lien vers un bon exemple? Je n'ai jamais utilisé de sélecteurs ...


github.com/reduxjs/reselect . J'espère que cela vous aidera.


Consultez également les documents de redux, ils sont très utiles pour expliquer comment et pourquoi ici


@ smashed-potatoes pourquoi avez-vous supprimé votre réponse?


@kingloui J'ai trop compliqué la solution - le filtrage HiRenS ainsi que l'utilisation de sélecteurs devraient vous conduire là où vous devez aller. Je peux le nettoyer et le ramener si cela vous intéresse.


@ pommes de terre écrasées ouais j'apprécierais ça! Merci :)


avez-vous pu aider davantage avec cette @ pommes de terre écrasées?


3 Réponses :


1
votes

Vous pouvez accéder aux clés d'objet en filtrant les données:

state.myRecommendations.filter (item => action.payload [item.type])


0 commentaires

2
votes

La suggestion de @ Yuvi d'utiliser un sélecteur est une bonne idée. Il vous permet de filtrer votre liste sans modifier l'état de votre réducteur. Ceci est important dans votre cas car avec votre approche actuelle chaque fois que vous changez de filtre, vous supprimerez plus de données de votre état, c'est-à-dire:

  1. Sélectionnez nourriture > mesRecommandations ne contient plus que des aliments articles maintenant
  2. Sélectionnez boutique > mesRecommandations est vide car les articles de la boutique ont été supprimés ci-dessus

Redux a une documentation expliquant comment procéder ici . Sans sélecteurs, vous auriez besoin d'un moyen de remplir à nouveau votre état mesRecommandations entre les appels de filtre.

En utilisant quelque chose comme reselect (voir here ) aidera les performances en mémorisant le sélecteur, mais le concept sous-jacent est de:

  1. Conservez les résultats non filtrés dans votre état
  2. Stockez votre sélection de filtre dans son propre état
  3. Filtrer les données là où elles sont nécessaires en fonction de l'état du filtre

ie:

filter.js - Définissez le filtre sélectionné

// 1. Bring in myRecommendations and recommendationsFilter from redux

// 2. Filter
/**
 * Get a filtered list of items, where the filter that matches
 * the recommendation 'type' is set to 'true'
 */
const filteredRecommendations = myRecommendations.filter(
  (item) => recommendationsFilter[item.type]
);

// 3. Now use filteredRecommendations as you would have used myRecommendations

Où que vous soyez vous définissez les noms de vos actions

export const reducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case SET_RECOMMENDATIONS_FILTER: {
      return {
        ...state,
        recommendationsFilter: action.filter,
      };
    }
  }
};

action.js

export const setRecommendationsFilter = (filter) => {
  return {
    type: SET_RECOMMENDATIONS_FILTER,
    filter,
};

reducer.js - Stockez le filtre sélectionné sans modifier les données des recommandations

const SET_RECOMMENDATIONS_FILTER = 'SET_RECOMMENDATIONS_FILTER';

Où vous utilisez les recommandations filtrées - Ceci est le concept de sélecteur

onButtonPress() {
  const { shop, food } = this.state;
  this.props.setRecommendationsFilter({ shop, food });
}

Lorsque vous utilisez quelque chose comme reselect, vous mettriez la logique qui crée les filteredRecommendations avec la logique pour obtenir les données dont vous avez besoin redux dans un sélecteur, puis utilisez ce sélecteur dans votre mapStateToProps (comme décrit ici ).


0 commentaires

0
votes

Cela peut vous convenir

En cliquant sur le bouton, vous pouvez passer le tableau pour tous les filtres

export const reducer = (state = INITIAL_STATE, action) => {
    switch (action.type) {
    case FILTER_RECOMMENDATIONS_BY_TYPE:
        return {
            ...state,
                myRecommendations: state.myRecommendations.filter(
            item => action.payload.includes(item.type)
            )
        };
};
export const filterRecommendations = (recommendationList ) => {
    return {
        type: FILTER_RECOMMENDATIONS_BY_TYPE,
        payload: recommendationList
    };
};
onButtonPress() {
    const { shop, food } 
    = this.state;

this.props.filterRecommendations([shop, food ]);


0 commentaires