我有一个谜。考虑下面的自定义React钩子,该钩子按时间段获取数据并将结果存储在Map
中:
export function useDataByPeriod(dateRanges: PeriodFilter[]) {
const isMounted = useMountedState();
const [data,setData] = useState(
new Map(
dateRanges.map(dateRange => [
dateRange,makeAsyncIsLoading({ isLoading: false }) as AsyncState<MyData[]>
])
)
);
const updateData = useCallback(
(period: PeriodFilter,asyncState: AsyncState<MyData[]>) => {
const isSafeToSetData = isMounted === undefined || (isMounted !== undefined && isMounted());
if (isSafeToSetData) {
setData(new Map(data.set(period,asyncState)));
}
},[setData,data,isMounted]
);
useEffect(() => {
if (dateRanges.length === 0) {
return;
}
const loadData = () => {
const client = makeclient();
dateRanges.map(dateRange => {
updateData(dateRange,makeAsyncIsLoading({ isLoading: true }));
return client
.getData(dateRange.dateFrom,dateRange.dateTo)
.then(periodData => {
updateData(dateRange,makeAsyncData(periodData));
})
.catch(error => {
const errorString = `Problem fetching ${dateRange.displayPeriod} (${dateRange.dateFrom} - ${dateRange.dateTo})`;
console.error(errorString,error);
updateData(dateRange,makeAsyncError(errorString));
});
});
};
loadData();
// eslint-disable-next-line react-hooks/exhaustive-deps
},[dateRanges /*,updateData - for some reason when included this triggers infinite renders */]);
return data;
}
将useEffect
添加为依赖项时,将反复触发updateData
。如果我将其排除为依赖项,那么一切都会按预期工作/运行,但eslint
抱怨我违反了react-hooks/exhaustive-deps
。
鉴于updateData
是useCallback
版,我不知所措,不明白为什么它应该反复触发渲染。有人可以照亮吗?