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

React分类图片画廊祖孙组件传type参数失效致图片无法渲染

React图片画廊参数传递失效导致图片不渲染问题修复

核心问题点

图片URL拼接错误本质是3个传参/作用域问题叠加导致的:

  • 父组件ImagesList调用useFetch时,没有把拿到的type(图片地址前缀参数)传给自定义Hook
  • useFetch内部的fetchData函数重复声明了view形参,调用时又没传值,导致函数内部拿到的view永远是undefined,直接覆盖了Hook外层接收到的参数
  • useFetch的useEffect依赖数组漏了图片前缀参数,参数变化时不会重新生成正确的图片地址

另外代码里还有3个会直接导致页面报错的问题:

  • ImagesList组件里渲染了未定义的变量eleven
  • JSX的map循环里写了位置错误的行注释// </div>,会被解析为正常文本触发渲染错误
  • 顶层分类组件(比如Books)的函数形参写法不规范,React组件只会把所有props合并为第一个参数传入,写两个形参无法正确拿到传入值
  • 循环渲染的列表项没加唯一key属性,img标签没加alt属性,会触发控制台告警

修复后代码

1. 最内层自定义Hook(useFetch.js)

去掉重复形参,补全参数传递和依赖项,修正async/await和then混用的写法:

import { useState, useEffect } from "react";

export const useFetch = (address, view) => {
  const [data, setData] = useState([]);
  const [error, setError] = useState();

  // 去掉fetchData重复声明的view形参,直接使用外层Hook接收到的view
  const fetchData = async () => {
    try {
      const res = await fetch(address);
      const json = await res.json();
      const finalData = json.map((elem) => {
        const imageUrl = `${view}${elem.id}`;
        return {
          id: elem.id,
          title: elem.title,
          image: imageUrl,
        };
      });
      setError(undefined);
      setData(finalData);
    } catch (e) {
      console.error("请求错误: ", e);
      setError(e);
    }
  };

  useEffect(() => {
    fetchData();
    // 补全依赖项,address或view变化时重新执行逻辑
  }, [address, view]);

  return { data, error };
};

注意:React 17+版本支持新的JSX转换,不需要在组件/Hook文件里显式导入React

2. 中间层列表组件(ImagesList.jsx)

调用Hook时传入type参数,删掉无效变量和错误注释,补全必要标签属性:

import { useFetch } from "./useFetch";

function ImagesList({ category, number, type }) {
  const address = `https://jsonplaceholder.typicode.com/albums/${number}/photos`;
  // 把type作为第二个参数传给useFetch,对应Hook里的view形参
  const { data, error } = useFetch(address, type);

  return (
    <div>
      <h1 className="header__title">{category}</h1>
      {error && <p>加载出错: {error.message}</p>}
      <main className="container">
        <div className="items-list" data-style="cards">
          {data.map((item) => (
            <div className="items-list__item item" key={item.id}>
              <img className="item__img" src={item.image} alt={item.title} />
              <div className="item__info">
                <div className="caption">
                  <h6 className="item__name text--center">{item.title}</h6>
                  <div className="item__description">
                    可替换为对应分类的统一描述内容
                  </div>
                  <p className="heart d-inline-block">
                    <button>加入收藏</button>
                  </p>
                </div>
              </div>
            </div>
          ))}
        </div>
      </main>
    </div>
  );
}

export default ImagesList;

3. 顶层分类组件(以Books为例,Albums、Movies写法完全一致,仅传入参数不同)

修正组件形参写法,保持参数传入正确即可:

import "../styles/images.css";
import "../styles/favorites.css";
import ImagesList from "./ImagesList";

// 未使用props参数时直接写空括号即可
const Books = () => {
  return (
    <ImagesList 
      category="Books" 
      number="2" 
      type="https://api.lorem.space/image/book?w=150&h=220&hash=$"
    />
  );
}

export default Books;

其余两个分类组件只需要修改传入的category、number、type三个属性值即可,不需要重复编写任何数据请求和渲染逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:15:35