React map循环内匹配条件的iframe无法正常渲染怎么办
问题根因
你能正常打印item?.key、静态写iframe能正常加载,说明key取值、iframe地址本身完全没问题,渲染失败是JSX语法逻辑错误导致的:
Array.map()渲染列表时,回调函数必须return需要渲染的JSX节点,你现在在if判断块里写了iframe代码,但没写return,这段JSX只是个没被返回的无效表达式,React根本拿不到要渲染的内容,自然不会显示。- 全量遍历数组做判断的写法冗余:如果接口返回多个匹配规则的视频,会重复渲染多个iframe;如果没匹配到对应视频,也没有兜底逻辑,容易出现空白区域。
- 条件判断用了非严格相等
==,存在隐式类型转换导致判断失效的潜在风险。
修复方法
不用绕弯处理循环取值,直接用Array.find()提前把符合规则的官方预告片筛选出来再渲染即可,逻辑更清晰,性能也更好,修正后的完整代码如下:
import axios from "axios"; import React, { useEffect, useState } from "react"; const Modal = ({ closeModal, id, name }) => { const [video, setVideo] = useState([]); useEffect(() => { axios .get( `https://api.themoviedb.org/3/movie/${id}/videos?api_key=<<api_key>>&language=en-US` ) .then((response) => { setVideo(response.data.results); }); }, [id]); // 补全依赖项,电影id变化时自动拉取对应视频列表 // 提前筛选符合规则的官方预告片 const officialTrailer = video.find( (item) => item?.type === "Trailer" && item?.name === "Official Trailer" ); return ( <div className="bg-black/60 fixed top-0 left-0 w-full h-screen "> <div className="flex h-screen justify-center items-center"> <div className="p-4 w-full max-w-2xl h-full md:h-auto"> <div className="relative bg-transparent rounded-lg shadow "> <div className="flex justify-between items-start p-4 rounded-t border-b"> <h3 className="text-xl font-semibold text-gray-200 ">{name}</h3> <button onClick={() => closeModal(false)} type="button" className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="defaultModal" > <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" > <path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd" ></path> </svg> </button> </div> <div className="p-6 space-y-6"> {/* 匹配到预告片才渲染iframe,可按需修改兜底内容 */} {officialTrailer ? ( <iframe width="560" height="315" src={`https://www.youtube.com/embed/${officialTrailer.key}`} title="YouTube video player" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen ></iframe> ) : ( <p className="text-gray-200">暂无官方预告片</p> )} </div> </div> </div> </div> </div> ); }; export default Modal;
如果你一定要保留map遍历的写法,只需要在if分支里加上return,不匹配的分支返回null即可,示例写法如下:
<div className="p-6 space-y-6"> {video.map((item) => { if (item?.type === "Trailer" && item?.name === "Official Trailer") { // 必须return JSX节点,React才能识别渲染 return ( <iframe key={item.id} width="560" height="315" src={`https://www.youtube.com/embed/${item.key}`} title="YouTube video player" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen ></iframe> ); } // 不满足条件的项返回null,不渲染内容 return null; })} </div>
内容的提问来源于stack exchange,提问作者Njoroge Brian
相关产品推荐
相关产品推荐

