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

React使用useEffect调用Reddit API次数过多,如何仅在query变更时触发?

问题根因

你当前使用的useEffect没有传入第二个依赖数组参数,这种情况下React会在组件每一次渲染完成后都执行Effect回调,无论哪个状态变更都会触发接口请求,就是你遇到的调用次数过多的问题。

修复方案

给useEffect补充依赖数组,仅将query作为依赖项放入,即可实现只有查询关键词变更时才触发请求的逻辑。同时为了避免内部函数重复创建带来的额外依赖问题,我们可以直接将请求逻辑写在useEffect内部,还可以新增请求中断逻辑避免内存泄漏。

修改后的代码如下:

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';

function Results()
{   
    const query = useSelector(state => state.query);
    const results = useSelector(state => state.results);
    const dispatch = useDispatch();

    useEffect(() => {
        // 空query时不发起无效请求
        if (!query.trim()) return;
        // 添加中断控制器,组件卸载/query变更时终止未完成的请求
        const controller = new AbortController();
        const signal = controller.signal;

        let postTitles = [];
        let postSrcs = [];

        fetch('https://www.reddit.com/r/' + query + '.json', { signal })
        .then(response => response.json())
        .then(body => {
            for (let i = 0; i < body.data.children.length; ++i) {
                if (body.data.children[i].data.post_hint === 'image')
                {
                    let img_url = body.data.children[i].data.url_overridden_by_dest;
                    postSrcs.push(img_url);
                }
                let title = body.data.children[i].data.title;
                postTitles.push(title);
            }
            dispatch({type: "QUERY_RESULTS", payload: postTitles})
        }).catch((err) => {
            // 忽略主动中断请求产生的报错
            if (err.name !== 'AbortError') {
                console.log(err)
            }
        });
        console.log("use effect triggered")

        // 清理函数,依赖变化/组件卸载时执行
        return () => controller.abort();
    }, [query, dispatch]) // 仅query、dispatch变化时触发Effect,dispatch为稳定引用不会频繁变更
    

    return (
        <>
        <h1>Query: {query}</h1>
        
        { !results 
        ? <h1>No Results</h1> 
        // 补充key属性避免React渲染警告
        : results.map((p, index) => <h6 key={index}> {p} </h6>)
        }

        </>
    )
}

export default Results;

补充说明

  • 依赖数组中的dispatch是React Redux提供的稳定引用,不会随着组件渲染发生变化,不会触发Effect重复执行
  • 请求中断逻辑属于优化项,如果你不需要可以直接删除,不影响核心功能的正常运行

内容的提问来源于stack exchange,提问作者ziad Sakr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:36:03