Updating
Upgrading from react-native-video v6 to v7
Version 7 of react-native-video introduces a significant architectural shift, separating the video player logic from the UI rendering. This change unlocks new capabilities like video preloading and a more intuitive, hook-based API. This guide will walk you through the necessary steps to migrate your application from v6 to v7.
Key Changes in v7
The most substantial change in v7 is the move from a monolithic <Video> component to a more modular approach with two distinct components:
VideoPlayer: A new class that manages the player's state and playback logic. It is not a UI component.VideoView: A UI component responsible for rendering the video on the screen. It takes aVideoPlayerinstance as a prop.useVideoPlayerhook: The recommended way to create and manage the lifecycle of aVideoPlayerinstance within a functional component. It automatically handles the creation and cleanup of the player.
New Dependency
react-native-video v7 is now built on top of react-native-nitro-modules framework. This means that you need to install the Nitro framework to use react-native-video v7.
Step-by-Step Migration Guide
1. Installation
First, update the react-native-video package to the latest v7 release:
npm install react-native-video@next --save
Then, install the pods for iOS:
cd ios && pod install
2. Updating Your Component
The core of the migration involves replacing the <Video> component with the new useVideoPlayer hook and <VideoView> component.
v6 Implementation:
import React, { useRef } from 'react';
import Video from 'react-native-video';
const VideoPlayerV6 = () => {
const videoRef = useRef(null);
return (
<Video
source={{ uri: 'https://www.w3schools.com/html/mov_bbb.mp4' }}
ref={videoRef}
style={{ width: 300, height: 200 }}
controls={true}
onLoad={() => console.log('Video loaded')}
onProgress={(data) => console.log('Progress:', data.currentTime)}
/>
);
};
v7 Implementation:
import React from 'react';
import { useVideoPlayer, VideoView, useEvent } from 'react-native-video';
const VideoPlayerV7 = () => {
const player = useVideoPlayer({
source: {
uri: 'https://www.w3schools.com/html/mov_bbb.mp4',
},
});
useEvent(player, 'onLoad', () => {
console.log('Video loaded');
});
useEvent(player, 'onProgress', (data) => {
console.log('Progress:', data.currentTime);
});
return (
<VideoView
player={player}
style={{ width: 300, height: 200 }}
controls={true}
/>
);
};
Prop and Method Migration
Many props and methods from the v6 <Video> component have been moved to the VideoPlayer instance in v7.
Common Props
v6 Prop (<Video>) | v7 Equivalent (VideoPlayer properties) | Notes |
|---|---|---|
source | source property in useVideoPlayer config | The structure of the source object remains largely the same. |
paused | paused property on the VideoPlayer instance | Can be controlled via player.pause() and player.play(). |
muted | muted property on the VideoPlayer instance | player.muted = true/false; |
volume | volume property on the VideoPlayer instance | player.volume = 0.5; |
rate | rate property on the VideoPlayer instance | player.rate = 1.5; |
loop | loop property on the VideoPlayer instance | player.loop = true; |
resizeMode | resizeMode prop on <VideoView> | This remains a prop on the UI component. |
controls | controls prop on <VideoView> | This also remains on the UI component. |
see VideoPlayer for more details.
Methods
Imperative methods previously called on the <Video> component's ref are now methods on the VideoPlayer instance.
v6 Method (videoRef.current) | v7 Equivalent (player) |
|---|---|
seek(time) | player.seekTo(time) |
presentFullscreenPlayer() | videoViewRef.current.enterFullscreen() |
dismissFullscreenPlayer() | videoViewRef.current.exitFullscreen() |
pause() | player.pause() |
resume() | player.play() |
see VideoPlayer for more details.
Event Handling
In v7, event handling is standardized through the useEvent hook or by directly assigning callbacks to the VideoPlayer instance. The useEvent hook is recommended as it automatically handles listener cleanup.
v6 Event Handling:
<Video
onLoad={(data) => console.log(data)}
onProgress={(data) => console.log(data.currentTime)}
onError={(error) => console.error(error)}
/>
v7 Event Handling with useEvent:
import { useVideoPlayer, VideoView, useEvent } from 'react-native-video';
const MyPlayer = () => {
const player = useVideoPlayer({ source: { uri: '...' } });
useEvent(player, 'onLoad', (data) => console.log(data));
useEvent(player, 'onProgress', (data) => console.log(data.currentTime));
useEvent(player, 'onError', (error) => console.error(error.code, error.message));
return <VideoView player={player} />;
}
Directly assigning callbacks in v7:
const player = useVideoPlayer('https://example.com/video.mp4', (_player) => {
_player.onLoad = (data) => {
console.log('Video loaded! Duration:', data.duration);
};
_player.onError = (error) => {
console.error('Player Error:', error.code, error.message);
};
});
Benefits of the New Architecture
- Preloading: You can create a
VideoPlayerinstance and begin loading a video before it's visible in the UI. When you're ready to display it, simply pass the player instance to a<VideoView>. - Improved Performance: Separating the player logic from the UI rendering can lead to better performance and a more responsive application.
- Cleaner API: The hook-based API simplifies player management and reduces boilerplate code, especially for handling the player's lifecycle.
- Full New Architecture Support: Version 7 fully embraces React Native's New Architecture, ensuring better performance and consistency.