I’m displaying an array of YouTube videos in this component (using react-player) and have gotten them to play when the custom play button is clicked, but it plays (and pauses) all of them instead of the currently selected item.
I’m using the useRef hook, and am having trouble figuring out how to reference a selected video and play only that video (using key and/or index):
Note: if I remove the useRef hook and ref from ReactPlayer, the videos do not play at all
import React, {useState, useRef} from 'react';
import {useStaticQuery, graphql} from 'gatsby';
import ReactPlayer from 'react-player';
import {Button} from '../Buttons/Button';
import './videos.scss';
import '../../Molecules/Cards/cards.scss';
const VideoCards = () => {
const { allVideoCardsJson } = useStaticQuery(
graphql`
query VideoQuery {
allVideoCardsJson {
edges {
node {
title
source
}
}
}
}
`)
let videoRef = useRef();
const [isPlaying, setIsPlaying] = useState(false);
const playVideo = () => {
// this plays/pauses all of the videos
setIsPlaying(!isPlaying);
// this plays the last video in the array
//videoRef.current.getInternalPlayer().playVideo()
}
return (
<div className="card-container__videos">
{allVideoCardsJson.edges.map(({node, index}) => (
<div className="video-card" key={index} isPlaying={isPlaying}>
<ReactPlayer
ref={videoRef}
url={node.source}
width="100%"
pip={true}
controls={true}
playing={isPlaying}
></ReactPlayer>
<Button onClick={playVideo} style={{zIndex:'200'}} label="Play Video"></Button>
</div>
))}
</div>
);
};
export default VideoCards;
UPDATE: I was able to move the eventHandler function into the Button and receive the same results (playing/pausing all videos) but I'm still having trouble figuring out how to reference a key/unique id and use it in the function:
<Button onClick={() => {
if(isPlaying) {
setIsPlaying(false);
} else {
setIsPlaying(true);
}
}} label="Play Video"></Button>
CodePudding user response:
isPlaying
is set outside of the map, and is not specific to any mapped index.
So you need to change isPlaying
to be specific to the mapped element. Create an object based off allVideoCardsJson
that contains boolean values for each item. Then, update them in playVideo
by making it take the index or some identifier as an argument.
CodePudding user response:
Instead of a Boolean, store the index of the video that is playing in isPlaying
Change the Button onClick to: onClicK={() => playVideo(index)}
Change the playVideo function:
const playVideo = i => setIsPlaying(i)
In ReactPlayer change the playing prop: playing={isPlaying === index}
You could probably remove the isPlaying prop from the containing div, not sure what that’s accomplishing