You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何控制useEffect执行时机,处理业务逻辑同时不触发eslint警告

解决方案

核心改造思路是把fetch函数依赖的动态参数从闭包捕获改为调用时传入,保证fetch函数引用稳定,从根源避免不必要的触发。

第一步:改造useCallback定义的fetch函数

将动态的页码、筛选条件改为入参,移除useCallback对currPage、filter的依赖,仅保留稳定的request作为依赖,改造后fetch函数引用永远不会变化:

const fetch = useCallback(async (page, filterParams) => {
    setLoading(true);
    // 调用外部传入的请求函数
    const { data, total } = await request({ current: page }, filterParams);
    setList(data);
    setTotal(total);
    setLoading(false);
}, [request]);

第二步:修改监听projectId的useEffect

现在fetch已经是稳定引用,useEffect仅会在projectId变更时触发,完全符合业务需求,也不会触发eslint校验告警:

useEffect(() => {
    const resetPage = 1;
    const resetFilter = {};
    // 同步更新状态
    setCurrPage(resetPage);
    setFilter(resetFilter);
    // 传入重置后的参数调用请求
    fetch(resetPage, resetFilter);
}, [projectId, fetch]);

第三步:实现搜索按钮点击逻辑

和projectId变更的逻辑保持一致即可:

const handleSearchClick = () => {
    const resetPage = 1;
    const resetFilter = {};
    setCurrPage(resetPage);
    setFilter(resetFilter);
    fetch(resetPage, resetFilter);
};

其他场景兼容

如果后续有翻页、修改筛选条件的请求需求,直接传入对应参数调用fetch即可,示例:

// 翻页场景
const handlePageChange = (newPage) => {
    setCurrPage(newPage);
    fetch(newPage, filter);
};

// 修改筛选条件场景
const handleFilterChange = (newFilter) => {
    const firstPage = 1;
    setCurrPage(firstPage);
    setFilter(newFilter);
    fetch(firstPage, newFilter);
};

原理解释

原有代码的问题在于fetch的useCallback依赖了频繁变化的currPage和filter状态,每次状态更新都会生成新的fetch函数,导致依赖fetch的useEffect被频繁触发,产生多余请求。
改造后fetch不再从闭包获取动态参数,所有可变参数都通过调用时传入,保证了函数引用的稳定性,同时完全符合eslint的Hooks校验规则,不会产生告警。


内容的提问来源于stack exchange,提问作者阿亮同学

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:36:04