javascript 如何在react中状态更新时停止videojs中的重新渲染

wnavrhmk  于 2023-01-11  发布在  Java
关注(0)|答案(1)|浏览(233)

我从https://videojs.com/guides/react/获得代码。
如果我更新状态,我的视频重新渲染和视频开始播放从第一,如何解决。
示例代码:

    • 视频代码:**
import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

export const VideoJS = (props) => {
  const videoRef = React.useRef(null);
  const playerRef = React.useRef(null);
  const {options, onReady} = props;

  React.useEffect(() => {

    // Make sure Video.js player is only initialized once
    if (!playerRef.current) {
      // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode. 
      const videoElement = document.createElement("video-js");

      videoElement.classList.add('vjs-big-play-centered');
      videoRef.current.appendChild(videoElement);

      const player = playerRef.current = videojs(videoElement, options, () => {
        videojs.log('player is ready');
        onReady && onReady(player);
      });

    // You could update an existing player in the `else` block here
    // on prop change, for example:
    } else {
      const player = playerRef.current;

      player.autoplay(options.autoplay);
      player.src(options.sources);
    }
  }, [options, videoRef]);

  // Dispose the Video.js player when the functional component unmounts
  React.useEffect(() => {
    const player = playerRef.current;

    return () => {
      if (player && !player.isDisposed()) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, [playerRef]);

  return (
    <div data-vjs-player>
      <div ref={videoRef} />
    </div>
  );
}

export default VideoJS;
    • 应用程序js**
import React from 'react';

// This imports the functional component from the previous sample.
import VideoJS from './VideoJS'

const App = () => {
  const playerRef = React.useRef(null);
  const [timestamp,setTimestamp]= useState(0) 
  const videoJsOptions = {
    autoplay: true,
    controls: true,
    responsive: true,
    fluid: true,
    sources: [{
      src: '/path/to/video.mp4',
      type: 'video/mp4'
    }]
  };

  const handlePlayerReady = (player) => {
    playerRef.current = player;

    // You can handle player events here, for example:
    player.on('waiting', () => {
      videojs.log('player is waiting');
    });

    player.on('dispose', () => {
      videojs.log('player will dispose');
    });

    player.on('timeupdate', function(){
    setTimestamp (player.currentTime()) 
   });
  };

  return (
    <>
      <div>Rest of app here</div>
      <VideoJS options={videoJsOptions} onReady={handlePlayerReady} />
      <div>Rest of app here</div>
    </>
  );
}

在App.js中,我更新了timeupdate侦听器中的时间戳,重新渲染,视频再次从第一个开始播放。
请帮我解决

csbfibhn

csbfibhn1#

由于Videojs文件中的onReady(播放器),视频正在重新渲染。onReady是从App.js文件(handlePlayerReady)进入VideoJS的prop。
当您尝试使用player.on('timeupdate ')函数设置App.js文件的时间戳状态时,函数运行,属性值转到Video js,然后它再次重新呈现,因为Videojs被 Package 在useEffect中。因此,我没有从App.js传递数据,而是更改了一些代码。

视频JS

import React from "react";
import videojs from "video.js";
import "video.js/dist/video-js.css";

export const VideoJS = (props) => {
  const videoRef = React.useRef(null);
  const playerRef = React.useRef(null);
  const { options, setTimestamp1 } = props;

  React.useEffect(() => {
    // Make sure Video.js player is only initialized once
    if (!playerRef.current) {
      // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
      const videoElement = document.createElement("video-js");

      videoElement.classList.add("vjs-big-play-centered");
      videoRef.current.appendChild(videoElement);

      const player = (playerRef.current = videojs(videoElement, options, () => {
        player.on("waiting", () => {
          videojs.log("player is waiting");
        });

        player.on("dispose", () => {
          videojs.log("player will dispose");
        });

        player.on("timeupdate", () => {
          setTimestamp1(player.currentTime());
        });
      }));

      // You could update an existing player in the `else` block here
      // on prop change, for example:
    } else {
      const player = playerRef.current;

      player.autoplay(options.autoplay);
      player.src(options.sources);
    }
  }, []);

  // Dispose the Video.js player when the functional component unmounts
  React.useEffect(() => {
    const player = playerRef.current;

    return () => {
      if (player && !player.isDisposed()) {
        player.dispose();
        playerRef.current = null;
      }
    };
  }, [playerRef]);

  return (
    <div data-vjs-player>
      <div ref={videoRef} />
    </div>
  );
};

export default VideoJS;

应用程序js

import React,{ useState, useEffect} from 'react';
// This imports the functional component from the previous sample.
import VideoJS from './VideoJS'

const App = () => {
  const playerRef = React.useRef(null);
  const [timestamp1,setTimestamp1]= useState(null);
  
  const videoJsOptions = {
    autoplay: true,
    controls: true,
    responsive: true,
    fluid: true,
    sources: [{
      src: 'dandelions.mp4',
      type: 'video/mp4'
    }]
  };

  return (
    <>
      <div>{timestamp1}</div>
      <VideoJS options={videoJsOptions} setTimestamp1={setTimestamp1}/>
      <div>{timestamp1}</div>
    </>
  );
}

export default App

在这里,您可以看到我删除了onReady函数,并将数据直接放入OnReady正在渲染的VideoJs中,我将setTimestamp作为一个属性发送,并更改VideoJs文件中的值。因此,重新渲染问题得到解决,您可以在App.js中使用状态值。

相关问题