React.js中传递数据到子组件后无法遍历对象数组的问题
问题核心
在Searchbar.js中成功获取API数据并能通过map打印,但传递给子组件ShowList.js后,直接打印数据正常,执行map却无输出,且无法用map遍历渲染内容。
关键问题点&修复方案
1. ShowList.js未将map结果关联到渲染逻辑(核心问题)
你当前的ShowList.js仅在函数体里执行map打印,但既没有保留map结果,也未将其嵌入返回的JSX中。组件首次渲染时showData是父组件初始的空数组,此时map不会触发打印;父组件更新showData后组件重新渲染,map本应执行,但因未关联渲染逻辑,导致你看不到预期的遍历效果。
修复后的ShowList.js:
import React from 'react' const ShowsList = ({ showData }) => { // 遍历数组生成可渲染的JSX元素,同时处理空数组场景 return ( <div className="shows-container"> {showData.length === 0 ? ( <p>暂无剧集数据,请搜索关键词</p> ) : ( showData.map((singleShow, index) => ( <div key={index} className="show-item" style={{ margin: '10px 0', padding: '10px', border: '1px solid #eee' }}> <h3>{singleShow.show.name}</h3> {/* 渲染剧集简介,API返回的summary是HTML字符串,用dangerouslySetInnerHTML解析 */} {singleShow.show.summary && <div dangerouslySetInnerHTML={{ __html: singleShow.show.summary }} />} </div> )) )} </div> ) } export default ShowsList
2. Searchbar.js的API请求URL存在冗余
你的请求URL写为https://api.tvmaze.com/search/shows?q=,同时通过config传递q参数,最终请求地址会变成https://api.tvmaze.com/search/shows?q=&q=xxx(xxx为搜索关键词)。虽然TVMaze API兼容这种写法,但规范写法应去掉URL末尾的q=:
const response = await axios.get(`https://api.tvmaze.com/search/shows`, config);
3. 父组件setState的异步特性注意
在handleSearch中,调用setShowData(response.data)后立即执行showData.map,此时showData还是更新前的空数组(setState是异步操作)。如果需要在数据更新后执行逻辑,应使用useEffect监听showData变化:
import { useState, useEffect } from 'react' // 在Searchbar组件内添加 useEffect(() => { if (showData.length > 0) { showData.map(singleShow => { console.log(singleShow) }) } }, [showData])
验证说明
修复后,ShowList.js会根据showData动态渲染每个剧集的信息,控制台也会在数据更新时打印每个元素。若仍有问题,可检查API返回的数据结构是否符合预期(TVMaze的/search/shows接口返回的是包含show对象的数组)。
内容的提问来源于stack exchange,提问作者Kaviraj J

