程序问答   发布时间:2022-05-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer?

开发过程中遇到useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer的问题如何解决?下面主要结合日常开发的经验,给出你关于useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer的解决方法建议,希望对你解决useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer有所启发或帮助;

我正在尝试测试 useFetch 自定义挂钩。这是钩子:

import React from 'react';

function fetchReducer(state,action) {
  if (action.type === `fetch`) {
    return {
      ...state,loading: true,};
  } else if (action.type === `success`) {
    return {
      data: action.data,error: null,loading: false,};
  } else if (action.type === `error`) {
    return {
      ...state,error: action.error,};
  } else {
    throw new Error(
      `Hello! This function doesn't support the action you're trying to do.`
    );
  }
}

export default function useFetch(url,options) {
  const [state,dispatch] = React.useReducer(fetchReducer,{
    data: null,});

  React.useEffect(() => {
    dispatch({ type: 'fetch' });

    fetch(url,options)
      .then((responsE) => response.Json())
      .then((data) => dispatch({ type: 'success',data }))
      .catch((error) => {
        dispatch({ type: 'error',error });
      });
  },[url,options]);

  return {
    loading: state.loading,data: state.data,error: state.error,};
}

这是测试

import useFetch from "./useFetch";
import { renderHook } from "@tesTing-library/react-hooks";
import { server,rest } from "../mocks/server";

function getAPIbegin() {
  return renderHook(() =>
    useFetch(
      "http://fe-intervIEw-API-dev.ap-southeast-2.elasticbeanstalk.com/API/begin",{ method: "GET" },1
    )
  );
}

test("fetch should return the right data",async () => {
  const { result,waitForNextupdate } = getAPIbegin();

  expect(result.current.loading).toBe(true);
  await waitForNextupdate();
  expect(result.current.loading).toBe(false);
  const response = result.current.data.question;
  expect(response.answers[2]).toBe("i think so");
});

// Overwrite mock with failure case

test("shows server error if the @R_197_10613@est fails",async () => {
  server.use(
    rest.get(
      "http://fe-intervIEw-API-dev.ap-southeast-2.elasticbeanstalk.com/API/begin",async (req,res,ctX) => {
        return res(ctx.status(500));
      }
    )
  );

  const { result,waitForNextupdate } = getAPIbegin();

  expect(result.current.loading).toBe(true);
  expect(result.current.error).toBe(null);
  expect(result.current.data).toBe(null);
  await waitForNextupdate();
  console.log(result.current);
  expect(result.current.loading).toBe(false);
  expect(result.current.error).not.toBe(null);
  expect(result.current.data).toBe(null);
});
  • 我只在运行测试时一直收到错误: “警告:超出最大更新深度。当组件在 useEffect 中调用 setState 时,可能会发生这种情况,但 useEffect 要么没有依赖项数组,要么每次渲染时依赖项之一发生变化。”

  • 错误来自TestHook:node_modules/@tesTing-library/react-hooks/lib/index.Js:21:23) 悬念中

我不知道如何解决这个问题。 URL 和选项必须在依赖数组中,并且运行 useEffect 不会改变它们,所以我不明白为什么它会导致这个循环。当我将它们从数组中取出时,测试成功了,但是当这些事情发生变化时,我需要再次运行效果。

有什么想法吗?

解决方法

试试这个。

function getAPIbegin(url,options) {
  return renderHook(() =>
    useFetch(url,options)
  );
}

test("fetch should return the right data",async () => {
  const url = "http://fe-interview-api-dev.ap-southeast-2.elasticbeanstalk.com/api/begin";
  const options = { method: "GET" };
  const { result,waitForNextupdate } = getAPIbegin(url,options);

  expect(result.current.loading).toBe(true);
  await waitForNextupdate();
  expect(result.current.loading).toBe(false);
  const response = result.current.data.question;
  expect(response.answers[2]).toBe("i think so");
});

我没有使用过 react-hooks-tesTing-library,但我的猜测是每当 React 被渲染时,发送到 RenderHook 的回调会被重复调用,导致每次传入不同的选项。

大佬总结

以上是大佬教程为你收集整理的useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer全部内容,希望文章能够帮你解决useEffect 无限循环仅在测试时发生,否则不会发生 - 尽管使用 useReducer所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。