Функциональные перехваты компонентов React —- Я хочу добавить функциональность воспроизведения / паузы в список видео (функциональный компонент)

#reactjs #react-hooks

#reactjs #реагирующие перехваты

Вопрос:

 const VideoList = ({ videoList }) => {
let stateArr:any=[]
for(let i=0;i<content.videoListItems.length;i  ){
stateArr[i]=true
}
const [iconDisplay, setIconHide] = useState(stateArr);   
const stopVideo=(e:any,index:any)=>{
stateArr[index]=true
e.target.parentElement.parentElement.previousSibling.pause();
}
const videoPlay=(e:any,index:any)=>{
stateArr[index]=false
e.target.parentElement.parentElement.previousSibling.play();
}
useEffect(() => {
setIconHide(stateArr);
}, []);
return (
<div>
   {videoListItems.map((item: any, index: number) => {    //rendering video list
   return (
   <div key={index}>
      <video src={item.video.url} />
      <span>
      {iconDisplay[index] amp;amp;<button onClick={(e:any)=>videoPlay(e,index)}>
      <img                               // rendering play image
         src="play.svg"
         alt="Play Icon"
         />
      </button>}
      {!iconDisplay[index] amp;amp; <button onClick={(e:any)=>stopVideo(e,index)}>
      <img
         src="pause.svg"                  //rendering pause image
         alt="Pause Icon"
         />
      </button>
      }
      </span>
   </div>
   )
   })
   }
</div>
)
}
 

Как я могу добиться этой функциональности? Я пытаюсь отобразить список видео и, основываясь на событии, нажимаю, пытаясь воспроизвести и приостановить, но почему-то я не могу отобразить изображение на паузе после 1-го щелчка

Комментарии:

1. Ваш let stateArr=[] и for all i's make stateArr[i] = true находится в цикле рендеринга. Этот код будет выполняться каждый раз при повторном рендеринге компонента, поэтому он не будет обновляться, как вы ожидаете. stateArr, вероятно, должен быть состоянием реакции (useState), и вы захотите обновить, создав новый объект stateArr, не изменяя оригинал.

2. Есть ли какая-либо причина, по которой вам может потребоваться узнать, какие видео в списке воспроизводятся? Вместо обновления элемента в массиве, я думаю, было бы намного проще, если бы вы отображали каждое видео через Video компонент, который управляет его собственным состоянием паузы / воспроизведения.

Ответ №1:

Вы делаете это слишком сложным, управляя своим состоянием в array . Это можно сделать, но изменять состояние с помощью настройки stateArr[index]=true — это не выход.

Вы можете сделать это намного проще для себя, если у вас есть Video компонент для каждого видео в списке, который внутренне обрабатывает свое собственное isPlaying состояние.

Я использую a ref для доступа к элементу video, а не для просмотра отношений DOM parent / sibling.

 import { useState, useRef } from "react";

type VideoProps = {
  src: string; // require an src
} amp; JSX.IntrinsicElements["video"]; // allow any other props of the HTML <video> element

const Video = (props: VideoProps) => {
  const videoRef = useRef<HTMLVideoElement>(null);

  const [isPlaying, setIsPlaying] = useState(false);

  const togglePlay = () => {
    // play or pause the video element
    if (isPlaying) {
      videoRef.current?.pause();
    } else {
      videoRef.current?.play();
    }
    // update the state
    setIsPlaying(!isPlaying);
  };

  return (
    <div>
      <video
        {...props} // pass through all props to the video element
        ref={videoRef} // attach the ref
      />
      <span>
        <button onClick={togglePlay}>
          <img
            src={isPlaying ? "pause.svg" : "play.svg"}
            alt={isPlaying ? "Pause" : "Play"}
          />
        </button>
      </span>
    </div>
  );
};

type VideoListProps = {
  videoListItems: Array<{
    video: {
      url: string;
    };
  }>;
};

const VideoList = ({ videoListItems }: VideoListProps) => {
  return (
    <div>
      {videoListItems.map((item) => (
        <Video key={item.video.url} src={item.video.url} />
      ))}
    </div>
  );
};