web-dev-qa-db-ja.com

fetch apiで使用すると、reactフックがactエラーをスローするのはなぜですか?

APIリクエストを作成して状態を更新するたびに、テストスイートでWarning: An update to App inside a test was not wrapped in act(...).を取得し続けます。

私は反応テストライブラリを使用しています。私はまた、ReactDOMテストユーティリティを使用してみましたが、同じ結果が得られました。私が試したもう1つのことは、コンテナをactでラップすることでしたが、それでも同じ結果が得られました。

注意してください:私のアプリは動作し、私のテストはパスしています。私は自分が何を間違っていたか、またはエラーが表示される原因となっているreact-domパッケージのバグかどうかを知る必要があるだけです。そして、コンソールエラーをモックしてミュートするのは悪いことです。

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);
});

フックの実装は次のとおりです。

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

act()警告を取り除くには、約束が同期的に解決されることを確認する必要があります。 こちら これを行う方法を読むことができます。

概要:

この解決策は少し複雑です。

  • promiseなどの「すぐに」Promiseを解決できる実装で、Promiseをグローバルにポリフィルします。
  • このリポジトリのようなカスタムバベルセットアップでJavaScriptをトランスパイルします
  • jest.runAllTimers();を使用します。これにより、promiseタスクキューもフラッシュされます
0
0xR