J'essaie de récupérer des données d'une API publique avec Axios et d'afficher ce que j'obtiens via une application React. Mais je ne trouve pas de condition dans mon componentDidUpdate () pour le rendre une seule fois, lorsque l'utilisateur modifie l'entrée. Quelqu'un aurait une idée?

Voici mon code:

import React, { Component } from 'react';
import axios from "axios";
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      input: "",
      output: []
    }
  }

  componentDidUpdate() {
    axios.get(`https://geo.api.gouv.fr/communes?nom=${this.state.input}`)
      .then(response => {
        this.setState((prevState) => {
          if (prevState.input !== this.state.input) {
            return { output: response.data };
          }
        });
      })
      .catch(function (error) {
        console.log(error);
      })
  }

  handleInput = (event, input) => {
    this.setState({input: event.target.value});
  }

  render() {
    return (
      <React.Fragment>
        <label>Recherche : <input type="text" onChange={this.handleInput} /></label>
        <div>
          {this.state.output.map((value, index) => <p key={index}>{value.nom}</p>)}
        </div>
      </React.Fragment>
    );
  }
}

export default App;

Merci pour ton aide.

3
Silvère MAZIERE 16 avril 2018 à 12:38

5 réponses

Meilleure réponse

En supposant que vous devez effectuer une action chaque fois que votre état change, vous devez vérifier si l'état a été mis à jour avant de déclencher un action dans componentDidUpdate sinon un appel API sera effectué chaque fois que votre composant sera mis à jour.

Si vous ne souhaitez appeler l'API qu'une seule fois, appelez-le dans componentDidMount

componentDidUpdate(prevProps, prevState) {

    if(prevState.input !== this.state.input) {
        axios.get(`https://geo.api.gouv.fr/communes?nom=${this.state.input}`)
          .then(response => {
            this.setState({ output: response.data });
          })
          .catch(function (error) {
            console.log(error);
          })
    }
}
2
Shubham Khatri 16 avril 2018 à 12:45

En supposant que vous devez prendre des mesures à chaque changement d'état ...

En fait, c'est ce que je voulais faire, et la solution que j'ai trouvée est d'envelopper la demande Axios dans un

if(prevState.input !== this.state.input) { --- }

Comme Shubham me l'a dit. Néanmoins, j'ai dû supprimer la condition interne setState () pour que cela fonctionne.

Merci à tout le monde !

0
Silvère MAZIERE 16 avril 2018 à 12:43

Le seul moment où vous souhaitez obtenir des données, c'est lorsque votre entrée a changé. Pourquoi ne pas utiliser la méthode pour déclencher la récupération? L'état est utilisé pour garder une trace de ce qui est entré et récupéré, mais vous ne devez pas vous fier au changement d'état pour déclencher une fonction dépendant des changements d'utilisateur .

Voir votre exemple transposé à ce que je pense être un bon exemple, avec mes commentaires: https://codesandbox.io/s / oxoxoym85y

0
ChrisR 16 avril 2018 à 10:41

Vous bouclez dans votre code: après la mise à jour de votre composant, componentDidUpdate sera invoqué; à l'intérieur de cette fonction, vous appelez setState qui restituera le composant. Cela déclenchera componentDidUpdate une autre fois et ainsi de suite ... Je pense que vous devriez simplement déplacer votre appel d'API de componentDidUpdate à componentDidMount.

1
Dario 16 avril 2018 à 09:41

Si vous devez appeler l'API une fois Vous pouvez utiliser componentWillMount, une fois que l'état a changé lorsque les données arrivent, votre composant se rendra

Ce n'est que si vous souhaitez utiliser votre API à tout moment que le rendu du composant vous permet d'utiliser componentDidUpdate, dans ce cas, assurez-vous que vous ne modifiez pas l'état pour éviter la boucle infinie.

0
bennyh 16 avril 2018 à 10:05