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

useEffect数据传递问题:如何将数据正确传递至子组件?

问题修复方案

1. 修复父组件的请求逻辑问题

你的父组件useEffect依赖里包含isDataLoaded,这会导致组件重复触发请求——每次请求完成后调用setIsDataLoaded(true),这个状态变化又会触发useEffect重新执行,即使数据已经加载完成。

修改父组件的useEffect依赖,只保留url:

const { url } = props;
const [products, setProducts] = useState([]);
const [loadingSpinner, setLoadingSpinner] = useState(false);
const [isDataLoaded, setIsDataLoaded] = useState(false);

useEffect(() => {
  const fetchProducts = async () => {
    setLoadingSpinner(true);
    try {
      const response = await fetch(url);
      const responseData = await response.json();
      const loadedProducts = [];

      for (const key in responseData) {
        loadedProducts.push({
          id: key,
          name: responseData[key].name,
          description: responseData[key].description,
          price: responseData[key].price,
          image: responseData[key].image,
          processor: responseData[key].processor,
        });
      }
      setProducts(loadedProducts);
      setIsDataLoaded(true);
    } catch (err) {
      console.error('请求产品数据失败:', err);
    } finally {
      setLoadingSpinner(false);
    }
  };
  fetchProducts();
}, [url]); // 移除isDataLoaded依赖

2. 优化子组件的product获取逻辑

子组件不需要额外维护product状态,直接用useMemo根据传入的products和路由参数计算目标产品,避免useState与props不同步的问题:

import { useParams, useMemo } from 'react';

function ProductDetail(props) {
  const params = useParams();
  
  // 用useMemo缓存计算结果,仅依赖变化时重新计算
  const product = useMemo(() => {
    if (!props.products.length || !params.productId) return null;
    return props.products.find(item => item.id === params.productId);
  }, [props.products, params.productId]);

  console.log(product);
  
  // 根据product状态渲染对应内容
  if (!product) {
    return <div>产品不存在或加载中...</div>;
  }
  
  return (
    <div>
      <h2>{product.name}</h2>
      <p>{product.description}</p>
      {/* 其他产品详情内容 */}
    </div>
  );
}

3. 额外优化:父组件控制子组件渲染时机

如果想避免子组件在数据未加载时处理空数组,可以在父组件里判断加载状态:

{loadingSpinner ? (
  <div>加载中...</div>
) : (
  <ProductDetail products={products} />
)}

这样能确保子组件只在数据准备完成后才开始处理,彻底解决初始空数组导致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:00:55