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

React遍历State存储列表传Props后内容不显示问题求助

问题:React组件遍历State列表传递Props后,仅渲染测试文本,视频及内容不显示

尝试遍历React组件State中的列表,将每个列表项作为Props传递给Video组件,期望渲染对应视频、标题和描述,但仅显示Video组件里的测试<h1>test</h1>,视频及相关内容未显示。

原代码

YoutubeFetch组件

export class YoutubeFetch extends Component {
  constructor(props) {
    super(props)

    this.state = {
      playlist: [],
      title: [],
      description: [],
      thumbnails: [],
    };
  }

  componentDidMount() {
    return fetch(url)
      .then((response) => response.json())
      .then((responseJson) => {
        // console.log('responseJson', responseJson)
        const playlist = responseJson.items.map(obj => "https://www.youtube.com/embed/" + obj.snippet.resourceId.videoId);
        this.setState({ playlist });
        const description = responseJson.items.map(obj => obj.snippet.description);
        this.setState({ description });
        const thumbnails = responseJson.items.map(obj => obj.snippet.thumbnails.default.url);
        this.setState({ thumbnails });
        const title = responseJson.items.map(obj => obj.snippet.title);
        this.setState({ title });
      })
      .catch((error) => {
        console.log(error)
      })
  }

  render() {
    return (
      <Container>
        <Row>
          {this.state.playlist.map((index) =>
            <Video
              key={index}
              video={this.state.playlist[index]}
              title={this.state.title[index]}
              description={this.state.description[index]}
            />
          )}
        </Row>
      </Container>
    )
  }
}

Video组件

function Video(props) {
  return (
    <Container>
      <Row>
        <h1>test</h1>
        <ReactPlayer
          controls
          url={props.video}
          // height="75%"
          playing={false}
          width="100%"
        />
      </Row>
      <Row>
        <h1>{props.title}</h1>
        <p>{props.description}</p>
      </Row>
    </Container>
  )
}

export default Video

问题分析

核心错误出在YoutubeFetch组件的render方法中:

  • this.state.playlist.map((index) => ...) 这里的index实际是playlist数组的元素值(即视频链接字符串),而非数组索引。
  • 后续用this.state.playlist[index]、this.state.title[index]取值时,因为index是字符串,会返回undefined,导致Video组件的props.video、props.title、props.description均为undefined,所以视频和文本内容无法渲染。

另外,componentDidMount中多次调用setState会触发多次组件渲染,建议合并为一次以提升性能。


修正方案

修正后的YoutubeFetch组件

export class YoutubeFetch extends Component {
  constructor(props) {
    super(props)

    this.state = {
      playlist: [],
      title: [],
      description: [],
      thumbnails: [],
    };
  }

  componentDidMount() {
    return fetch(url)
      .then((response) => response.json())
      .then((responseJson) => {
        // 一次性提取所有数据并更新state,避免多次渲染
        const playlist = responseJson.items.map(obj => "https://www.youtube.com/embed/" + obj.snippet.resourceId.videoId);
        const description = responseJson.items.map(obj => obj.snippet.description);
        const thumbnails = responseJson.items.map(obj => obj.snippet.thumbnails.default.url);
        const title = responseJson.items.map(obj => obj.snippet.title);
        
        this.setState({ 
          playlist, 
          description, 
          thumbnails, 
          title 
        });
      })
      .catch((error) => {
        console.log(error)
      })
  }

  render() {
    return (
      <Container>
        <Row>
          {this.state.playlist.map((videoUrl, index) =>
            <Video
              key={index}
              video={videoUrl}
              title={this.state.title[index]}
              description={this.state.description[index]}
            />
          )}
        </Row>
      </Container>
    )
  }
}

关键修改点

  1. 调整map函数参数为(videoUrl, index):第一个参数是当前视频链接(数组元素),第二个是数组索引
  2. 直接传递video={videoUrl},title和description通过index对应取值
  3. 合并setState调用,一次性更新所有State字段,减少不必要的渲染

进阶优化(可选)

可以将数据整理为对象数组,避免多数组同步的潜在问题:

// componentDidMount中修改
const videos = responseJson.items.map(obj => ({
  url: "https://www.youtube.com/embed/" + obj.snippet.resourceId.videoId,
  title: obj.snippet.title,
  description: obj.snippet.description,
  thumbnail: obj.snippet.thumbnails.default.url
}));
this.setState({ videos });

// render中修改
{this.state.videos.map((video, index) =>
  <Video
    key={index}
    video={video.url}
    title={video.title}
    description={video.description}
  />
)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 18:45:30