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

React子组件API调用两次排查(Strict Mode已关闭)

子组件重复渲染与API调用两次的原因及修复方案

核心原因

1. 父组件UserDetails的两次渲染触发子组件重复渲染

useParams()在路由初始化过程中可能存在**先返回空参数对象,再加载到正确userId**的情况,导致父组件先后渲染两次:

  • 第一次渲染:params.userId为undefined,子组件接收undefined作为userId
  • 第二次渲染:params.userId获取到有效值223,子组件接收新的userId

这两次父组件渲染会直接触发子组件的两次渲染,进而导致子组件的useEffect执行两次。

2. 子组件useEffect依赖数组缺失关键参数

子组件的useEffect中使用了props.userId,但未将其加入依赖数组,这会引发两个问题:

  • 当userId更新时,useEffect不会主动触发,导致请求可能使用旧的userId值(闭包陷阱)
  • 若父组件因userId变化重新渲染子组件,useEffect可能因其他依赖的隐式变化(比如对象引用)重复执行

修复方案

步骤1:修复父组件的参数处理

给params.userId添加默认值,仅在参数有效时渲染子组件,减少不必要的渲染:

export const UserDetails = () => {
  const params = useParams(); 
  // 解构时赋予默认值,避免传递undefined
  const userId = params?.userId || '';

  useEffect(() => {
    if(userId){
       getCustomerDetails(userId)
    }
  }, [userId]);

  return (
    <div>
      {/* 只在userId有效时渲染子组件 */}
      {userId && (
        <>
          <UserSpecificData1 userId={userId}/>
          <UserSpecificData2 userId={userId}/>
        </>
      )}
    </div>
  );
};

步骤2:补全子组件useEffect的依赖数组

将props.userId加入useEffect的依赖数组,确保userId变化时能重新触发API请求,同时避免闭包问题:

// 以UserSpecificData1为例,UserSpecificData2做相同修改
const UserSpecificData1 = props => {
  const [currentPage, setCurrentPage] = useState(0);
  const [filteredBy, setFilteredBy] = useState({});
  const [sortBy, setSortBy] = useState('ASC');

  useEffect(() => {
    // 仅当userId有效时发起请求
    if(!props.userId) return;
    getSpecificDataOne({
      id: props.userId,
      filteredBy: filteredBy,
      page: currentPage,
      size: 10,
      sortBy: sortBy,
    })
  }, [sortBy, currentPage, filteredBy, props.userId]); // 加入props.userId

  return <div></div>
};

步骤3:优化引用类型依赖(可选)

由于filteredBy是对象类型,若后续需要修改它,建议使用useMemo缓存对象,避免因引用变化触发不必要的useEffect执行:

// 使用useMemo缓存filteredBy,确保引用稳定
const filteredBy = useMemo(() => ({}), []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:55:20