web-dev-qa-db-fra.com

Comment récupérer des données quand un React composant prop change?

Un identifiant est attribué à mon composant TranslationDetail lors de son ouverture. Un appel d'api externe est alors déclenché dans le constructeur de la classe. Il reçoit les données dans l'état et les affiche dans TranslationDetail.

//Routing:
<Route path="/translation/:id" component={TranslationDetail}/>

//Class:    
class TranslationDetail extends Component {
  constructor(props){
    super(props);

    this.props.fetchTrans(this.props.params.id);
  }

Tout cela fonctionne bien si j'entre l'URL manuellement. Dans le cas où je voudrais utiliser react-router, par exemple pour afficher l'élément suivant comme ci-dessous, l'URL change, mais l'appel de l'API n'est pas déclenché et les données restent les mêmes.

<button 
  type="button"
  onClick={() => 
    browserHistory.Push(`/translation/${Number(this.props.params.id)+1}`)}>
  Next
</button>

S'il vous plaît gardez à l'esprit que je suis un débutant total. La raison pour laquelle cela se produit est que je crois que le constructeur n’est exécuté qu’une seule fois. Par conséquent, aucun autre appel d’API n’est déclenché.

Comment puis-je résoudre ça? Dois-je répertorier les accessoires et appeler une fonction sur le changement? Si oui comment?

40
balu000

Constructor n'est pas le bon endroit pour faire des appels d'API.

Vous devez utiliser des événements de cycle de vie:

Assurez-vous de comparer les accessoires avec les accessoires précédents dans componentDidUpdate pour éviter d'aller chercher si l'accessoire qui vous tient à cœur n'a pas changé.

class TranslationDetail extends Component {    
   componentDidMount() {
     this.fetchTrans();
   }

   componentDidUpdate(prevProps) {
     if (prevProps.params.id !== this.props.params.id) {
       this.fetchTrans();
     }
   }

   fetchTrans() {
     this.props.fetchTrans(this.props.params.id);
   }
}
79
Yury Tarabanko

À partir de React 16.3 et versions ultérieures componentWillMount, componentWillUpdate et componentWillReceiveProps sont obsolète .

Vous pouvez utiliser static getDerivedStateFromProps et renvoyer un nouvel état basé sur les modifications apportées aux accessoires.

Vous n’avez pas accès à vos objets this comme des accessoires, vous ne pouvez donc pas comparer nextProps avec votre props actuel par nextProps.sth !== this.props.sth. Vous pouvez vous comparer prevState valeur avec nextProps et renvoyer une nouvelle valeur d'état.

Faites en sorte que vous ajoutiez UNSAFE_ à votre componentWillMount actuelle et aux autres méthodes de cycle de vie déconseillées pour le moment.

5
Kevin

Utilisez composantWillMount pour obtenir les données et définir l'état. Ensuite, utilisez ComponentWillReceiveProps pour capturer la mise à jour sur les accessoires.

Vous pouvez vérifier le Spécifications des composants et cycle de vie .

2

Je voudrais utiliser la méthode de rendu. Si les données ne sont pas chargées, je vais rendre un chargeur spinner et lancer l'action qui va chercher les données. Pour cela, j'utilise généralement les magasins. Une fois que le magasin a récupéré les données de l’API, marquez les données comme étant chargées, lancez un événement et laissez le composant extraire les données du magasin, en remplaçant le chargeur spinner par votre représentation des données.

0
Carlos