web-dev-qa-db-fra.com

Pourquoi le crochet réactif renvoie-t-il l'erreur d'acte lorsqu'il est utilisé avec fetch api?

Je continue à obtenir Warning: An update to App inside a test was not wrapped in act(...). dans ma suite de tests chaque fois que je fais une demande d'API et que je mets à jour l'état.

J'utilise la bibliothèque react-testing. J'ai également essayé d'utiliser les utilitaires de test ReactDOM, j'ai obtenu le même résultat. Une autre chose que j'ai essayée était d'encapsuler le conteneur dans act, toujours le même résultat.

Veuillez noter que: Mon application fonctionne et mon test réussit. J'ai juste besoin de savoir ce que je faisais mal ou si c'est un bogue dans le paquet react-dom qui fait apparaître cette erreur. Et il est mauvais de se moquer de l'erreur de la console et de la couper.

global.fetch = require('jest-fetch-mock');

it('should clear select content item', async () => {
    fetch.mockResponseOnce(JSON.stringify({ results: data }));

    const { container } = render(<App />);

    const content = container.querySelector('.content');

    await wait();

    expect(content.querySelectorAll('.content--item').length).toBe(2);
});

Voici l'implémentation du hook:

const [data, setData] = useState([]);
const [error, setError] = useState('');

const fetchInitData = async () => {
    try {
        const res = await fetch(API_URL);
        const data = await res.json();

        if (data.fault) {
            setError('Rate limit Exceeded');
        } else {
            setData(data.results);
        }
    } catch(e) {
        setError(e.message);
    }
};

useEffect(() => {
    fetchInitData();
}, [isEqual(data)]);
8
Ademola Adegbuyi

Pour vous débarrasser de l'avertissement act(), vous devez vous assurer que vos promesses se résolvent de manière synchrone. Vous pouvez lire ici comment faire cela.

Résumé:

La solution pour cela est un peu impliquée:

  • nous polyfill Promise globalement avec une implémentation qui peut résoudre les promesses "immédiatement", comme promesse
  • transpilez votre javascript avec une configuration babel personnalisée comme celle de ce repo
  • utilisez jest.runAllTimers (); cela videra également la file d'attente des tâches promises
0
0xR