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

React.js动态生成JSX渲染轮播组件遇问题求解决方案

问题描述

我从API获取数据后,尝试创建一个包含图片、标题和描述的轮播组件,但渲染出来的内容前总是带有undefined前缀,而且始终是字符串格式,无法正常解析为HTML。我试过用dangerouslySetInnerHTML结合String.raw${x}``的方法,这在其他场景有效,但在这里不管用。以下是我的代码:

export function CarouselImages({ projTitle, uid }) {
  const [json, setJson] = useState({});

  useEffect(() => {
    get_slide_data(projTitle).then(setJson).catch(console.error);
  }, [projTitle]);
  console.log(json.TheMovieDBAPI);

  let Indicators = () => {
    let temp;
    for(let i in json.TheMovieDBAPI){
      if(i == 1){
        temp += `<button type="button" data-bs-target=${uid} data-bs-slide-to=${(i-1)} className="active" aria-label=${"Slide " + (i)} aria-current="true"></button>`
      }else{
        temp += `<button type="button" data-bs-target=${uid} data-bs-slide-to=${(i-1)} className="" aria-label=${"Slide " + (i)} aria-current="true"></button>`
      }
    }
    return temp;
  };

  let Slides = () => {
    let temp;
    for(let i in json[projTitle]){
      temp += `<div class="carousel-item active">
                <img src=${i.src} class="d-block">
                <div class="carousel-caption d-none d-md-block">
                  <h5 class="h5">${i.heading}</h5>
                  <p>${i.desc}</p>
                </div>
              </div>`;
    }
    return temp;
  };

  console.log(Indicators);

  return (
    <div className="carousel slide projImg py-2" id={uid} data-bs-ride="carousel">
      <div className="carousel-indicators">
        <Indicators />
      </div>
      <div className="carousel-inner">
        <Slides />
      </div>
    </div>
  )
}
解决方案

1. 消除undefined前缀

你在Indicators和Slides组件里初始化temp时未赋值,默认值为undefined,字符串拼接时会把这个undefined带到结果里。只需把let temp;改成let temp = '';即可解决。

2. 正确渲染HTML(避免字符串格式)

React不会自动解析HTML字符串,而且字符串拼接生成HTML存在XSS风险,更推荐用JSX语法直接渲染元素:

重构Indicators组件

const Indicators = () => {
  if (!json?.TheMovieDBAPI) return null; // 数据未加载或不存在时返回null
  return Object.entries(json.TheMovieDBAPI).map(([key, _], index) => (
    <button
      key={key}
      type="button"
      data-bs-target={`#${uid}`} // 注意添加#,符合Bootstrap选择器要求
      data-bs-slide-to={index}
      className={index === 0 ? "active" : ""}
      aria-label={`Slide ${index + 1}`}
      aria-current={index === 0 ? "true" : "false"}
    />
  ));
};

重构Slides组件

const Slides = () => {
  if (!json?.[projTitle]) return null;
  return Object.entries(json[projTitle]).map(([key, item], index) => (
    <div key={key} className={`carousel-item ${index === 0 ? "active" : ""}`}>
      <img 
        src={item.src} 
        className="d-block w-100" 
        alt={item.heading || "轮播图片"} // 添加alt属性优化 accessibility
      />
      <div className="carousel-caption d-none d-md-block">
        <h5 className="h5">{item.heading}</h5>
        <p>{item.desc}</p>
      </div>
    </div>
  ));
};

3. 其他优化建议

  • 初始状态改为useState(null),方便判断数据是否加载完成,避免访问未定义属性报错:
    const [json, setJson] = useState(null);
    
  • 在主组件渲染前添加加载状态:
    if (!json) return <div>加载中...</div>;
    
  • for...in遍历对象可能会包含原型链上的属性,用Object.entries更安全,同时能正确获取索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:06:26