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

刷新商品详情页出现undefined is not an object错误的求助

问题原因

刷新页面时,React Query缓存中不存在"products"键对应的数据,导致queryClient.getQueryData("products")返回undefined,此时直接访问data.products就会触发undefined is not an object (evaluating 'data.products')错误。首次访问时缓存从列表页继承而来,所以能正常获取数据,刷新后缓存清空就出现了问题。

修复方案

1. 给缓存数据添加空值校验

获取partialProduct前先判断data是否存在,避免直接访问不存在的products属性。

2. 兼容缓存为空的占位数据逻辑

当没有缓存的商品列表数据时,设置通用的占位内容,而非依赖partialProduct生成占位数据。

3. 对partialProduct的访问添加空值保护

组件中所有直接使用partialProduct的地方,都要加上空值判断,防止缓存为空时报错。

修改后的代码示例
import React from 'react';
import styled from "styled-components";
import { useQuery, useQueryClient } from "react-query";
import { loadProduct } from '../../data/api/api'
import { useParams } from 'react-router-dom';

function Detail({images=[] }) {

  const { id } = useParams();
  const queryClient = useQueryClient();
  const data = queryClient.getQueryData("products");
  // 空值校验,避免data为undefined时访问products
  const partialProduct = data?.products?.find((p) => String(p.id) === id);
  
  // 兼容partialProduct不存在的场景,设置默认占位数据
  const placeholderData = partialProduct 
    ? {
        ...partialProduct,
        overview: "...",
        images: "...",
      }
    : {
        title: "加载中...",
        overview: "...",
        images: []
      };

  const { data: product, isLoading } = useQuery(
    ["currentProduct", { id }],
    () => loadProduct(id),
    { placeholderData }
  );

  // 加载状态提示
  if (isLoading && !product) {
    return <div>加载中...</div>;
  }
  
  return (
    <Main>
      <Header>
        <Title>{product.title}</Title>
        
        <Description>
          {product.overview} 

          {/* 空值保护,避免images不存在时访问length */}
          {partialProduct?.images?.length || 0} image

          {/* 空值保护,确保images存在再执行map */}
          {partialProduct?.images?.map(({image}) => (
            <li key={image}>
              <img
                src={`http://127.0.0.1:8000/api/products${image}`}
                className='card-img-top'
                alt="商品图片"
              />
            </li>
          ))}
        </Description>
        
    
      </Header>

    </Main>
  )
}
export default Detail;
额外优化建议

如果希望刷新页面时仍能保留products缓存,可以在应用初始化阶段预取商品列表数据,或者在useQuery中配置staleTime和cacheTime参数延长缓存有效期,避免刷新后缓存立即清空。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:02:53