自定义React Hook返回值引发useEffect无限循环问题求助
解决useCountries Hook引发useEffect无限循环的问题
问题根源
每次组件重渲染时,useCountries里通过concat生成的combinedCountries都是新数组实例——哪怕数组内容完全没变,React的依赖对比机制也会判定它是新值,导致依赖数组包含countries的useEffect反复执行,形成无限循环。
最优解决方案:在Hook内部缓存数组
直接修改useCountries,用useMemo缓存合并后的数组,确保只有当原始国家数据变化时,才生成新数组:
export function useCountries() { const { data: countryData, isLoading } = useQuery<ICountries, string>(["countries"], () => fetchCountries(), { refetchOnWindowFocus: false, onError: (err) => { error("Could not get countries!, " + err); }, }); // 用useMemo缓存合并结果,依赖原始数据字段 const combinedCountries = useMemo(() => { return (countryData?.prioritizedCountries || []).concat(countryData?.countries || []); }, [countryData?.prioritizedCountries, countryData?.countries]); return { countries: combinedCountries, isFetchingCountries: isLoading, }; }
这样只要countryData里的prioritizedCountries和countries内容不变,返回的countries数组引用就不会变,useEffect就不会无故触发。
额外排查点
如果修改后仍有循环,检查useEffect里的setSettingsFromCountryChange是否会更新settings:
- 如果这个方法会修改
settings,那么settings变化又会触发useEffect,形成新的循环 - 此时可以在调用
setSettingsFromCountryChange前加判断,只有当目标内容和当前settings不一致时才执行:
const countryInfo = countries.find((country) => country.id === settings?.treatmentCountryGuid); if (countryInfo && settings?.legalDepartmentGuid && settings?.defaultLanguage) { // 对比关键字段,避免不必要的更新 if (settings.treatmentCountryGuid !== countryInfo.id) { setSettingsFromCountryChange(countryInfo); } }
内容的提问来源于stack exchange,提问作者ComCool
相关产品推荐
相关产品推荐

