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
相关产品推荐
相关产品推荐

