1
votes

React, comment faire une inclusion sur un tableau dans un objet demandé par axios

Je fais un projet dans lequel j'ai un élément qui peut avoir plusieurs catégories. Les identifiants de catégorie sont stockés dans l'objet d'élément sous forme de tableau. Je veux pouvoir afficher les noms des catégories.

dans le code ci-dessous, j'essaye d'obtenir les catégories (chats) de mon backend. Utilisez ensuite une méthode de filtrage avec un paramètre include pour récupérer les objets désirés.

Cependant, j'obtiens une erreur "Impossible de lire la propriété 'includes' of undefined", sur la ligne où j'essaye this.state. prod.cat.inclut (cats.id).

import React, { Component } from "react";
import axios from "axios";

import { Link } from "react-router-dom";

class items extends Component {
    state = {
        item: {},
        cats: []
    };

    componentDidMount() {
        axios
            .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
            .then(response => {
                this.setState({ item: response.data });
            })
            .catch(error => {
                console.log(error);
            });
    }

    render() {
        axios
            .get("http://localhost:5001/cats")
            .then(response => {
                this.setState({
                    cats: response.data.filter(cats =>
                        this.state.item.cat.includes(cats.id)
                    )
                });
            })
            .catch(error => {
                console.log(error);
            });
        return (
            <div>
                {this.state.cats.map(({ _id, name }) => (
                    <Link exact to={"/category/" + _id}>
                        <span>{name}</span>
                    </Link>
                ))}
            </div>
        );
    }
}

export default items;


1 commentaires

Salut Sean, vérifiez ma solution et faites-moi savoir si cela aide.


3 Réponses :


0
votes

Vous obtenez une erreur car, le composant est d'abord rendu avec son état initial. Au départ, vous avez item: {} , donc quand vous faites this.state.item.cat.includes (cats.id) cela vous donne l'erreur.

I pense que vous ne devriez pas appeler l'API dans la méthode de rendu.

componentDidMount est le meilleur endroit pour appeler votre API.

Vous pouvez utiliser le rappel dans setState pour votre appel d'API,

componentDidMount() {
  axios
    .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
    .then(response => {
        this.setState({ 
           item: response.data 
        }, () => {   //Call your API here
            axios
              .get("http://localhost:5001/cats")
              .then(response => {
                this.setState({
                  cats: response.data.filter(cats =>
                    this.state.item.cat.includes(cats.id)
                  )
                });
              })
              .catch(error => {
                console.log(error);
              });
        })
    })
    .catch(error => {
        console.log(error);
    });
}


0 commentaires

0
votes

utilisez componentDidMount pour appeler votre API. componentDidMount récupérera les données de l'API après l'appel de la fonction de rendu.

import React, { Component } from "react";
import axios from "axios";

import { Link } from "react-router-dom";

class items extends Component {
    state = {
        item: {},
        cats: []
    };

    componentDidMount() {
        axios
         .get("http://localhost:5001/items/5d722a4e630c27623003dfcb")
            .then(response => {
                this.setState({ item: response.data });
            })
            .then(()=>{
                   axios
            .get("http://localhost:5001/cats")
            .then(response => {
                this.setState({
                    cats: response.data.filter(cats =>
                        this.state.item.cat.includes(cats.id)
                    )
                });
            })
            })
            .catch(error => {
                console.log(error);
            });
    }

    render() {
        return (
            <div>
                {this.state.cats.map(({ _id, name }) => (
                    <Link exact to={"/category/" + _id}>
                        <span>{name}</span>
                    </Link>
                ))}
            </div>
        );
    }
}

export default items;


0 commentaires

0
votes

Il est fortement déconseillé d'utiliser Render () pour les effets secondaires (appels d'API). Déplacez le code vers ComponentdidMount. Les fonctions de rendu reçoivent un appel à chaque fois que l'état change, donc ce n'est certainement pas une bonne idée de faire un appel d'API dans Render. CONSEIL: Utilisez useEffect dans les composants fonctionnels pour les appels d'API.

Voici comment procéder

 componentDidMount() {

  axios.all([
    axios.get('http://localhost:5001/cats'),
    axios.get('http://localhost:5001/items/5d722a4e630c27623003dfcb')
  ])
  .then(axios.spread((cats, items) => {
    // do something with both responses
  }));

    }

Une alternative

 componentDidMount() {
        axios.get('http://localhost:5001/cats')
  .then((res) => {
    // do something with cat Res

    return axios.get('http://localhost:5001/items/5d722a4e630c27623003dfcb');
  })
  .then((res) => {
    // do something with items res
  })
  .catch((err) => {
    // handle err
  });



0 commentaires