React中useEffect漏加customFetch触发ESLint报错,加后无限循环如何解决?
问题根因
你当前的useFetch自定义Hook每次调用都会返回一个全新的异步函数引用,组件每次渲染时customFetch的值都会发生变化。如果将它加入useEffect依赖数组,每次渲染都会触发useEffect重新执行,若useEffect内部修改了组件状态导致重渲染,就会触发无限循环。
修复方案
方案1:修改useFetch缓存返回函数(推荐)
用useCallback包裹useFetch返回的异步函数,由于react-redux提供的dispatch是稳定引用,不会随渲染变化,因此缓存后的函数引用也会保持稳定,加入依赖数组后不会触发不必要的重执行。
修改后的useFetch代码如下:
import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; const useFetch = () => { const dispatch = useDispatch(); // 用useCallback缓存函数,依赖只有稳定的dispatch return useCallback(async (callback, ...props) => { try { return await callback(...props); } catch (error) { // 这里顺便修复原代码的小问题:如果error.response.data不存在,不能直接对字符串解构 const { msg } = error.response?.data || { msg: "Something went wrong" }; dispatch(showModal(msg)); setTimeout(() => dispatch(hideModal()), 3000); } }, [dispatch]); };
修改完成后直接把customFetch加入useEffect依赖数组即可,不会再触发无限循环:
const customFetch = useFetch(); useEffect(() => { (async () => { const data = await customFetch(fetchUsers, token); if (data) setUsers(data.user); })(); }, [token, customFetch]); // 加入稳定的customFetch依赖
方案2:用useRef缓存customFetch(无需修改useFetch)
如果不方便修改useFetch的源码,可以用useRef存储customFetch的引用,ref本身是稳定值,不需要加入useEffect依赖数组:
import { useRef, useEffect } from 'react'; const customFetch = useFetch(); const fetchRef = useRef(customFetch); // 同步更新ref中存储的最新customFetch useEffect(() => { fetchRef.current = customFetch; }, [customFetch]); useEffect(() => { (async () => { const data = await fetchRef.current(fetchUsers, token); if (data) setUsers(data.user); })(); }, [token]); // 无需加入customFetch依赖
方案3:临时忽略ESLint检查(不推荐)
如果只是临时解决问题,可以加注释跳过依赖检查,但后续customFetch逻辑变更时容易出现隐藏bug,不建议长期使用:
useEffect(() => { (async () => { const data = await customFetch(fetchUsers, token); if (data) setUsers(data.user); })(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [token]);
内容的提问来源于stack exchange,提问作者adramelech
相关产品推荐
相关产品推荐

