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

ReactJS:componentDidMount中API调用6次的原因及解决办法

嘿,我来帮你捋捋这个问题——你的componentDidMount里的axios请求被调用了6次,这确实挺闹心的,咱们一步步拆解可能的原因,再说说解决办法和替代方案:

为啥会触发这么多次请求?

这些是最常见的几个原因,你可以对照排查:

  • 组件反复挂载/卸载:如果你的组件在页面里被多次渲染、卸载再挂载(比如路由频繁切换、父组件state变化导致子组件反复重建),componentDidMount就会跟着每次挂载执行一次请求。比如父组件的某个状态频繁更新,子组件没做优化,每次都重新挂载,次数就会叠加。
  • React严格模式(Strict Mode)的锅:开发环境下,React的Strict Mode会刻意重复调用一些生命周期方法(包括componentDidMount),用来帮你检测潜在的bug。虽然一般是两次,但如果结合了其他因素(比如组件本身被多次实例化),次数就会变多。
  • 组件被多次实例化:要是你的组件在页面多个地方被使用,或者在列表循环里渲染了6次,每个实例都会执行自己的componentDidMount,请求次数自然就和实例数一致了。
  • 状态更新引发的连锁重渲染:如果请求的then回调里调用了setState,而这个状态更新又触发了组件或父组件的重渲染,要是没做渲染优化,可能会陷入“请求→更新状态→重渲染→再请求”的循环?不过一般不会直接到6次,但叠加其他因素也有可能。

解决办法&替代方案

先搞定重复调用的根本问题

  • 先确认组件挂载次数:在componentDidMount里加一行console.log('组件挂载啦'),看看输出次数是不是6次。如果是,就去排查组件被重复实例化或者反复挂载的原因——比如是不是路由配置重复了,或者父组件的条件渲染导致它反复出现消失。
  • 临时关闭Strict Mode排查:如果是开发环境,你可以把index.js里的<React.StrictMode>标签去掉试试,看看请求次数会不会减少。不过这只是排查手段,生产环境Strict Mode不会生效,别永久去掉哦。
  • 优化组件渲染:
    • 类组件可以改成PureComponent,或者自己实现shouldComponentUpdate方法,只有当props/state真的变化时才允许重渲染。
    • 要是后续转成函数组件,用React.memo包裹组件,防止不必要的重渲染。
  • 临时用防抖/节流限制请求:虽然不是根本解决办法,但可以应急。比如用lodash的_.debounce包裹请求,避免短时间内多次发送:
import _ from 'lodash';

componentDidMount(){
  const fetchData = _.debounce(() => {
    axios.get(`${this.state.url}tables`, { headers: { 'authorization': token } })
      .then(response => {
        // 处理state更新逻辑
      })
  }, 1000); // 1秒内只执行一次
  fetchData();
}

更靠谱的生命周期/函数替代

  • 类组件用componentDidUpdate配合条件判断:如果是因为状态变化需要重新请求,别只在componentDidMount里执行,把请求抽成单独方法,然后在componentDidUpdate里判断条件再调用:
componentDidMount() {
  this.fetchData();
}

componentDidUpdate(prevProps, prevState) {
  // 只有当url变化时才重新请求,避免重复调用
  if (prevState.url !== this.state.url) {
    this.fetchData();
  }
}

fetchData() {
  axios.get(`${this.state.url}tables`, { headers: { 'authorization': token } })
    .then(response => {
      const { regions, state, directory } = response.data.data;
      this.setState({ regions, state, directory });
    })
}
  • 转用函数组件的useEffect:如果可以重构组件,函数组件的useEffect会更灵活,通过依赖数组能精准控制请求时机。空依赖数组的话,请求只会在组件挂载时执行一次:
import { useEffect, useState } from 'react';

function YourComponent() {
  const [url, setUrl] = useState('你的初始url');
  const [regions, setRegions] = useState([]);
  const [state, setState] = useState({});
  const [directory, setDirectory] = useState({});

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(`${url}tables`, { 
          headers: { 'authorization': token } 
        });
        const { regions, state, directory } = response.data.data;
        setRegions(regions);
        setState(state);
        setDirectory(directory);
      } catch (err) {
        console.error('请求失败:', err);
      }
    };
    fetchData();
  }, []); // 空依赖数组,仅挂载时执行一次

  // 组件渲染逻辑
  return (
    // ...你的JSX
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:51:41