如何在列表中逐个呈现项目做出反应?

问题描述 投票:1回答:3

我想一次渲染一个视频缩略图,以便我可以提高我的网站的性能。

我尝试过使用地图但是地图一次遍历所有项目并返回要渲染的组件列表

我也试过使用while循环,但while循环只渲染一个缩略图(第一个缩略图)

这是我的渲染方法

render(){
        const { videos } = this.state;
        const listVideos = () => {
            let vids = videos
            let loopedAllVids = false;
            while(!loopedAllVids){
                const head = R.head(vids); // returns first item
                const { thumbnail } = head;
                vids = R.tail(vids); // returns all items but first item
                if(vids.length === 0){
                    loopedAllVids = true;
                }
                return(
                    <div 
                      className='video' 
                      style={{background:`url(${thumbnail})`}}>
                    </div>
                )
            }
        }
        return(
            <div  className="row text-center">
                <div className="col-md-12 header">
                    <h1> My Youtube Videos </h1>
                </div>
                <div className="col-md-12">
                    <div className="row">
                        <div className="col-md-8 col-xs-12 col-md-offset-2 videos">
                            {videos.length> 0 && listVideos()}
                        </div>
                    </div>
                </div>
            </div>
        )
    }
javascript arrays reactjs ramda.js
3个回答
1
投票

while方法只返回一个thumb,因为“return”语句停止while循环,map方法在迭代第一个后返回一个新数组。

无论如何,我认为这不是实现目标的正确方法。我认为将拇指存储在组件状态并将其一个接一个地递增(可能使用“setTimeout”方法)会更好。

另一种方法是查看已经存在的“Lazyload”解决方案(例如https://github.com/twobin/react-lazyload)。


1
投票

其他人已经解释了你的while循环有什么问题,所以我不会再说了。

如果您希望在给定时间仅呈现列表的子集,则需要实现分页。您仍然可以使用map渲染该子集。

对于分页,你可以使用slice

const videos = [
  {id: 0},
  {id: 1},
  {id: 2},
  {id: 3},
  {id: 4},
  {id: 5},
  {id: 6},
  {id: 7},
  {id: 8},
  {id: 9}
];

slice(0, 3, videos);  // 0, 1, 2
slice(3, 6, videos);  // 3, 4, 5
slice(6, 9, videos);  // 6, 7, 8
slice(9, 12, videos); // 9

我也会(正如其他人的建议)将视频渲染提取到一个单独的功能中。

这是一个渲染一个缩略图的功能。它接受一个视频对象,但对其进行解构以仅采用它所需的内容:

const renderThumbnail = ({thumbnail}) => (
  <div class="video" style={{background: url(`${thumbnail}`)}}></div>
);

这是一个接受要呈现的视频列表的函数:

const renderThumbnails = map(renderThumbnail);

这就是你在render函数中使用它的方法:

render() {
  // videoIndex, displayCount: assuming you have implemented pagination somehow
  const { videos, videoIndex, displayCount } = this.state;
  return (
      <div  className="row text-center">
          <div className="col-md-12 header">
              <h1> My Youtube Videos </h1>
          </div>
          <div className="col-md-12">
              <div className="row">
                  <div className="col-md-8 col-xs-12 col-md-offset-2 videos">
                      {videos.length > 0 && renderThumbnails(slice(videoIndex, videoIndex + displayCount, videos))}
                  </div>
              </div>
          </div>
      </div>
  )
}

0
投票

return语句打破while循环,你应该在render函数之外移动函数。

listVideos = (videos) => {

  let vids = videos
  let loopedAllVids = false;

  const videosToRender = []

  while(!loopedAllVids){

    const head = R.head(vids); // returns first item
    const { thumbnail } = head;

    vids = R.tail(vids); // returns all items but first item

    if(vids.length === 0){
       loopedAllVids = true;
    }

    videosToRender.push(
      <div 
         className='video' 
         style={{background:`url(${thumbnail})`}}>
       </div>
      )
    }

    return videosToRender;
}

render() {

  const { videos } = this.state;
  return(
      <div  className="row text-center">
          <div className="col-md-12 header">
              <h1> My Youtube Videos </h1>
          </div>
          <div className="col-md-12">
              <div className="row">
                  <div className="col-md-8 col-xs-12 col-md-offset-2 videos">
                      {videos.length > 0 && this.listVideos(videos)}
                  </div>
              </div>
          </div>
      </div>
  )

}
© www.soinside.com 2019 - 2024. All rights reserved.