diff --git a/docs/guides/react.md b/docs/guides/react.md index 3c79f6170a..627aa57319 100644 --- a/docs/guides/react.md +++ b/docs/guides/react.md @@ -12,43 +12,55 @@ import "video.js/dist/video-js.css"; export const VideoJS = ( props ) => { const videoRef = React.useRef(null); - const { options } = props; + const playerRef = React.useRef(null); + const { options, onReady } = props; - // This separate functional component fixes the removal of the videoelement - // from the DOM when calling the dispose() method on a player - const VideoHtml = ( props ) => ( -
-
- ); + React.useEffect(() => { + // make sure Video.js player is only initialized once + if (!playerRef.current) { + const videoElement = videoRef.current; + if (!videoElement) return; - React.useEffect( () => { - const videoElement = videoRef.current; - let player; - if( videoElement ) { - player = videojs( videoElement, options, () => { + const player = playerRef.current = videojs(videoElement, options, () => { console.log("player is ready"); + onReady && onReady(player); }); + } else { + // you can update player here [update player through props] + // const player = playerRef.current; + // player.autoplay(options.autoplay); + // player.src(options.sources); } + }, [options]); + + // Dispose the Video.js player when the functional component unmounts + React.useEffect(() => { return () => { - if( player ) { - player.dispose(); + if (playerRef.current) { + playerRef.current.dispose(); + playerRef.current = null; } - } - }, [options]); + }; + }, []); - return (); + return ( +
+
+ ); } -export default VideoJS; +export default VideoJS; ``` You can then use it like this: (see [options guide][options] for option information) + ```jsx import React from "react"; import VideoJS from './VideoJS' // point to where the functional component is stored const App = () => { + const playerRef = React.useRef(null); const videoJsOptions = { // lookup the options in the docs for more options autoplay: true, @@ -60,18 +72,40 @@ const App = () => { type: 'video/mp4' }] } - + + const handlePlayerReady = (player) => { + playerRef.current = player; + + // you can handle player events here + player.on('waiting', () => { + console.log('player is waiting'); + }); + + player.on('dispose', () => { + console.log('player will dispose'); + }); + }; + + // const changePlayerOptions = () => { + // // you can update the player through the Video.js player instance + // if (!playerRef.current) { + // return; + // } + // // [update player through instance's api] + // playerRef.current.src([{src: 'http://ex.com/video.mp4', type: 'video/mp4'}]); + // playerRef.current.autoplay(false); + // }; + return ( <>
Rest of app here
- - - + + +
Rest of app here
); } - ``` ## React Class Component Example @@ -103,7 +137,7 @@ export default class VideoPlayer extends React.Component { // see https://github.com/videojs/video.js/pull/3856 render() { return ( -
+
@@ -127,9 +161,8 @@ const videoJsOptions = { return ``` -[options]: /docs/guides/options.md - +[options]: /docs/guides/options.md ## Using a React Component as a Video JS Component @@ -178,7 +211,7 @@ class vjsEpisodeList extends vjsComponent { player.ready(() => { this.mount(); }); - + /* Remove React root when component is destroyed */ this.on("dispose", () => { ReactDOM.unmountComponentAtNode(this.el())