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

ReactJS:如何检测其他组件的数值变化并与旧值对比,避免不必要的API调用

问题根因

你当前的实现逻辑里,useEffect将props.id作为依赖项,只要props.id(也就是点击Click Me按钮修改的数值)发生变化,useEffect就会自动执行触发接口请求,这是不符合预期的核心原因,额外引入的usePrevious没有起到拦截作用,反而被加入依赖项进一步放大了问题。

修复方案

按照你的需求,只有点击Call API按钮才触发请求,完全不需要用useEffect来监听参数变化,调整逻辑如下:
把接口请求逻辑封装为独立函数,通过useImperativeHandle暴露给父组件,父组件点击Call API按钮时主动调用该函数即可,此时拿到的props.id就是当前最新的数值,完全符合要求。

调整后的GetAPIData组件代码

import { useState, useImperativeHandle, forwardRef } from 'react';
import axios from 'axios';

const GetAPIData = forwardRef((props, ref) => {
  const [chars, setChars] = useState([]);

  // 暴露请求方法给父组件
  useImperativeHandle(ref, () => ({
    fetchData: () => {
      axios
        .get(`https://rickandmortyapi.com/api/character/?page=${props.id}`)
        .then((res) => {
          setChars(res.data.results);
        })
        .catch((err) => {
          alert(err.message);
        });
    }
  }));

  return (
    <div className="container">
      <h3>
        <span>Achtung,</span> ein Trend geht um
      </h3>
    </div>
  );
});

export default GetAPIData;

父组件对应调整

// 父组件内创建ref关联子组件
const apiRef = useRef();
// 存储Click Me按钮对应的数值
const [count, setCount] = useState(1);

// Click Me按钮点击逻辑,仅修改count
const handleClickCount = () => setCount(prev => prev + 1);

// Call API按钮点击逻辑,主动调用子组件的请求方法
const handleCallApi = () => apiRef.current?.fetchData();

// 组件渲染
return (
  <>
    <GetAPIData ref={apiRef} id={count} />
    <button onClick={handleClickCount}>Click Me</button>
    <button onClick={handleCallApi}>Call API</button>
  </>
)

如果不想用ref调用的方式,也可以在父组件多维护一个requestPage状态:点击Click Me仅修改count,点击Call API时才把count赋值给requestPage,把requestPage作为props传给GetAPIData,此时useEffect依赖requestPage即可,只有requestPage变化时才会发请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 11:09:03