React - play media after items are loaded with array.map()

余生颓废 提交于 2021-01-29 13:40:00

问题


I'm using react-player to render youtube videos with map(), like so:

class Jukebox extends Component {
  constructor (props) {
    super(props);
    this.state = {
     youtube_urls:[],      
     clients:[],        
    };
  };

  componentDidMount() {
    if (this.props.isAuthenticated) {
      this.getItems();
    }
  };

  getItems(event) {
    const {userId} = this.props
    const options = {
      url: `${process.env.REACT_APP_WEB_SERVICE_URL}/jukebox/${userId}`,
      method: 'get',
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': true,
        Authorization: `Bearer ${window.localStorage.authToken}`
      }
    };
    return axios(options)
    .then((res) => { 
      console.log(res.data)  
      console.log(res.data.data) 
      this.setState({
        clients: res.data.data[0].clients,
        youtube_urls:res.data.data[0].youtube_urls
      })
    })
    .catch((error) => { console.log(error); });
  };

render() {
 const { youtube_urls } = this.state;
 return (
  <div>      
   <h1 className="title is-1">Jukebox</font></h1>
  {
   clients.map((client, index) => {
     /* 
    Obtain preview from state.previews for current artist index 
    */
    const audio = youtube_urls[index]
    /* 
    Render current client data, and corresponding audio url
    */
    return(
      <div key={index}>
      <ul>
        <ReactPlayer 
          url={ audio }
          controls
          playing // <--- does not work
          width='50'
          height='150'
        />
        <div className="Line" />
      </ul></div>
     )
   })
 })
};

According to to one the library props, playing (see above), you can play media automatically when render finishes, but if I use map() this will result in all videos playing at the same time.

At the same time, there is the callback prop onReady():

Called when media is loaded and ready to play. If playing is set to true, media will play immediately.


QUESTION:

How do I implement this and have all videos play, from index 0 on, one at at time, after all media is loaded?


回答1:


I'd use two state variables: videosLoadedCount, playingIndex. Initialize videosLoadedCount at 0 and playingIndex at -1.

You can deduce the playing props from the playingIndex state value.

Whenever there's an onReady, increment videosLoadedCount. When it reaches the number of videos, you can increment playingIndex. Whenever there is a onEnded callback, you increment playingIndex.


Something like this should work:

class Jukebox extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loadedVideosCount: 0,
      currentPlayingIndex: -1,
    };
  }

  render() {
    const { youtube_urls } = this.props;
    const { loadedVideosCount, currentPlayingIndex } = this.state;

    return (
      <div>
        {youtube_urls.map((url, index) => (
          <ReactPlayer
            url={url}
            controls
            onLoaded={() =>
              this.setState(currentState => ({
                loadedVideosCount: loadedVideosCount + 1,
                currentPlayingIndex:
                  loadedVideosCount + 1 === youtube_urls.length ? 0 : -1,
              }))
            }
            onEnded={() =>
              this.setState(currentState => ({
                currentPlayingIndex: currentPlayingIndex + 1,
              }))
            }
            playing={index === currentPlayingIndex} // <--- does not work
            width="50"
            height="150"
          />
        ))}
      </div>
    );
  }
}


来源:https://stackoverflow.com/questions/58793514/react-play-media-after-items-are-loaded-with-array-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!