web-dev-qa-db-fra.com

Comment utiliser axios dans Effect Hook?

Composant basé sur une classe:

componentDidMount() {
    axios.get('https://jsonplaceholder.typicode.com/posts').then((res) => {
        this.setState({
            posts: res.data.slice(0, 10)
        });
        console.log(posts);
    })
}

J'ai essayé ceci:

const [posts, setPosts] = useState([]);

useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts').then((res) => {
        setPosts(res.data.slice(0, 10));
        console.log(posts);
    })
});

Il crée une boucle infinie. Si je passe un []/{} comme deuxième argument [1] [2], il bloque tout appel ultérieur. Mais cela empêche également la mise à jour du tableau.

[1] Boucle infinie dans useEffect

[2] Comment appeler la fonction de chargement avec React useEffect une seule fois

6
Mahmudul Haque

Donner un tableau vide comme deuxième argument à useEffect pour indiquer que vous ne voulez que l'effet ne s'exécute qu'une fois après le rendu initial est le chemin à parcourir. La raison pour laquelle console.log(posts); vous montre un tableau vide est parce que la variable posts fait toujours référence au tableau initial et setPosts est également asynchrone, mais cela fonctionnera toujours comme vous le souhaitez si utilisé dans le rendu.

Exemple

const { useState, useEffect } = React;

function App() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    setTimeout(() => {
      setPosts([{ id: 0, content: "foo" }, { id: 1, content: "bar" }]);
      console.log(posts);
    }, 1000);
  }, []);

  return (
    <div>{posts.map(post => <div key={post.id}>{post.content}</div>)}</div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>

<div id="root"></div>
5
Tholle

Vous pouvez vérifier comment axios-hooks est implémenté.

C'est super simple et utilise l'objet de configuration (ou l'URL) que vous fournissez pour décider quand faire une demande et quand ne pas le faire, comme expliqué dans Réponse de Tholle .

En plus de vous permettre d'utiliser les axios impressionnants dans vos composants fonctionnels sans état, il prend également en charge le rendu côté serveur, qui - il s'avère - les crochets sont très simples à mettre en œuvre.

Avertissement: je suis l'auteur de ce package.

2
Simone

J'ai écrit un crochets personnalisés pour Axios.js.

Voici un exemple:

import React, { useState } from 'react';

import useAxios from '@use-hooks/axios';

export default function App() {
  const [gender, setGender] = useState('');
  const {
    response,
    loading,
    error,
    query,
  } = useAxios({
    url: `https://randomuser.me/api/${gender === 'unknow' ? 'unknow' : ''}`,
    method: 'GET',
    options: {
      params: { gender },
    },
    trigger: gender,
    filter: () => !!gender,
  });

  const { data } = response || {};

  const options = [
    { gender: 'female', title: 'Female' },
    { gender: 'male', title: 'Male' },
    { gender: 'unknow', title: 'Unknow' },
  ];

  if (loading) return 'loading...';
  return (
    <div>
      <h2>DEMO of <span style={{ color: '#F44336' }}>@use-hooks/axios</span></h2>
      {options.map(item => (
        <div key={item.gender}>
          <input
            type="radio"
            id={item.gender}
            value={item.gender}
            checked={gender === item.gender}
            onChange={e => setGender(e.target.value)}
          />
          {item.title}
        </div>
      ))}
      <button type="button" onClick={query}>Refresh</button>
      <div>
        {error ? error.message || 'error' : (
          <textarea cols="100" rows="30" defaultValue={JSON.stringify(data || {}, '', 2)} />
        )}
      </div>
    </div>
  );
}

Vous pouvez voir le résultat en ligne .

0
int64ago