javascript - 当我包含依赖项时,useEffect 无限循环
问题描述
我正在尝试创建一个自定义 useFetch 钩子,它适用于除一个之外的每个组件。在这一个组件中,它无限循环(但没有那么多 React 停止它)。这是钩子:
import { useState, useEffect, SetStateAction, Dispatch } from 'react';
import axios, { AxiosResponse } from 'axios';
const useFetch = (
method: 'POST' | 'GET',
url: string,
object?: any
): [
AxiosResponse,
'Loading' | 'Rendered' | 'Error',
Dispatch<SetStateAction<'Loading' | 'Rendered' | 'Error'>>
] => {
const [data, setData] = useState<AxiosResponse | null | void>(null);
const [compState, setCompState] = useState<'Loading' | 'Rendered' | 'Error'>('Loading');
useEffect(() => {
let isMounted = true;
setCompState('Loading');
if (method === 'GET') {
// ...
} else if (
method === 'POST' &&
object !== null &&
!Object.values(object).includes(null)
) {
axios
.post(url, object)
.then(res => {
if (isMounted) {
console.log(res.data);
setCompState('Rendered');
setData(res);
}
})
.catch(err => {
if (isMounted) {
console.log(err);
setCompState('Error');
setData(err);
}
});
} else return;
return () => {
isMounted = false;
};
}, [url, object]);
return [data as AxiosResponse, compState];
};
export default useFetch;
这就是我在组件中使用它的方式:
const userId = localStorage.getItem('userId');
const [orders, compState] = useFetch('POST', '/orders', { userId });
我知道导致循环的部分原因;这是因为我object
在依赖数组中有 ,如果我从数组中删除它,它就会停止循环。问题是我需要object
数组中的 ,因为在这种情况下,对象只是 userId,我希望组件在用户登录此页面时重新呈现。我认为有关 userId 常量的某些内容是导致此问题的原因。
在我提取自定义钩子之前,常量在 useEffect 中,这不是问题,但我想知道他们是否有一种解决此问题的方法,不会影响钩子的可重用性。
解决方案
如果您想要对该对象进行深度属性比较,则不应将objects
其作为第二个参数的数组项传递,因此如果您需要对s 属性进行深度比较,最好的方法是使用如下:useEffect
object
use-deep-compare-effect
import useDeepCompareEffect from 'use-deep-compare-effect';
// Later in our components
useDeepCompareEffect(() => {
let isMounted = true;
setCompState('Loading');
if (method === 'GET') {
// ...
} else if (
method === 'POST' &&
object !== null &&
!Object.values(object).includes(null)
) {
axios
.post(url, object)
.then(res => {
if (isMounted) {
console.log(res.data);
setCompState('Rendered');
setData(res);
}
})
.catch(err => {
if (isMounted) {
console.log(err);
setCompState('Error');
setData(err);
}
});
} else return;
return () => {
isMounted = false;
};
}, [url, object]);
推荐阅读
- python - 为什么 sympy Sum 函数不能计算这个总和?
- python - Windows 10 的 ADAFFRUIT_PCA9865 库问题
- python - 当 Tkinter 需要无限次读取文件时,它只在循环中读取一次文件
- python - 如何在 Python 和 Postgres 的文本列中搜索一系列整数
- ffmpeg - 如何使用 ffmpeg 和 gstremer 获得相同的结果(通过控制台流式传输 mpeg-ts)
- handlebars.js - 车把部分不显示在物化卡中?
- python - 跨应用程序中的多个子进程共享 PyJulia 实例
- stream - java流管道创建列表映射
- c# - 如何在 C# 中将类名转换为 T?
- python - 如何使用 tf.random.uniform 并且不生成重复项