# @vjs-10/react-media-store > React hooks and context for Video.js media store [![npm](https://img.shields.io/badge/npm-%40vjs--10%2Freact--media--store-blue)](https://www.npmjs.com/package/@vjs-10/react-media-store) **Status:** Early Development > **⚠️ PROTOTYPE - SUBJECT TO CHANGE** > > This package is in early prototype phase. Expect significant changes including: > > - Package restructuring and naming > - Breaking API changes > - Major architectural updates > - Incomplete or experimental features > > Not recommended for production use. ## Overview `@vjs-10/react-media-store` provides React-specific integration for `@vjs-10/media-store`. It offers hooks and context providers for accessing and manipulating media state in React applications, enabling reactive UI updates across your player components. ## Key Features - **React Hooks** - Easy access to media state in functional components - **Context Provider** - Share media store across component tree - **Reactive Updates** - Automatic re-renders on state changes - **Type Safe** - Full TypeScript support with React types - **SSR Safe** - Works with server-side rendering - **Optimized** - Minimal re-renders with fine-grained subscriptions ## Installation ```bash npm install @vjs-10/react-media-store ``` **Peer Dependencies:** - `react` >=16.8.0 ## Quick Start ### Basic Usage with Context ```tsx import { MediaStoreProvider, useMediaStore } from '@vjs-10/react-media-store'; function App() { return ( ); } function CustomControls() { const store = useMediaStore(); const paused = store.paused.get(); return ( ); } ``` ### Without Context (Local Store) ```tsx import { createMediaStore } from '@vjs-10/react-media-store'; import { useMemo } from 'react'; function VideoPlayer() { const store = useMemo(() => createMediaStore(), []); return (
); } ``` ## Hooks ### useMediaStore Access the media store from context: ```tsx import { useMediaStore } from '@vjs-10/react-media-store'; function Component() { const store = useMediaStore(); // Access state const paused = store.paused.get(); const currentTime = store.currentTime.get(); const volume = store.volume.get(); // Update state const handlePlay = () => store.paused.set(false); const handleSeek = (time: number) => store.currentTime.set(time); return
{/* JSX */}
; } ``` ### useMediaState Subscribe to specific state values: ```tsx import { useMediaState } from '@vjs-10/react-media-store'; function CurrentTimeDisplay() { const currentTime = useMediaState(store => store.currentTime); const duration = useMediaState(store => store.duration); return (
{formatTime(currentTime)} {' '} / {formatTime(duration)}
); } ``` ### useMediaValue Get reactive value from store atom: ```tsx import { useMediaStore, useMediaValue } from '@vjs-10/react-media-store'; function VolumeControl() { const store = useMediaStore(); const volume = useMediaValue(store.volume); return ( store.volume.set(Number.parseFloat(e.target.value))} /> ); } ``` ### usePlaybackState Access playback-specific state: ```tsx import { usePlaybackState } from '@vjs-10/react-media-store'; function PlaybackControls() { const { paused, ended, seeking } = usePlaybackState(); if (ended) return ; if (seeking) return ; return paused ? : ; } ``` ### useTimeState Access time-related state: ```tsx import { useTimeState } from '@vjs-10/react-media-store'; function TimeInfo() { const { currentTime, duration, buffered } = useTimeState(); const progress = (currentTime / duration) * 100; return (
{formatTime(currentTime)} {' '} / {' '} {formatTime(duration)}
); } ``` ### useVolumeState Access volume-related state: ```tsx import { useVolumeState } from '@vjs-10/react-media-store'; function VolumeControls() { const { volume, muted, setVolume, toggleMute } = useVolumeState(); return (
setVolume(Number.parseFloat(e.target.value))} />
); } ``` ## Context Provider ### MediaStoreProvider Provides media store to component tree: ```tsx import { MediaStoreProvider } from '@vjs-10/react-media-store'; function App() { return ( {/* All children can access the store */} ); } ``` ### With Custom Store ```tsx import { createMediaStore, MediaStoreProvider } from '@vjs-10/react-media-store'; import { useMemo } from 'react'; function App() { const store = useMemo(() => { const store = createMediaStore(); // Initialize with custom values store.volume.set(0.8); store.muted.set(false); return store; }, []); return ( ); } ``` ### Multiple Stores ```tsx import { MediaStoreProvider } from '@vjs-10/react-media-store'; function MultiPlayerApp() { return (
); } ``` ## Advanced Usage ### Custom Play Button ```tsx import { PauseIcon, PlayIcon } from '@vjs-10/react-icons'; import { useMediaStore, useMediaValue } from '@vjs-10/react-media-store'; function PlayButton() { const store = useMediaStore(); const paused = useMediaValue(store.paused); const handleClick = () => { store.paused.set(!paused); }; return ( ); } ``` ### Progress Bar with Seeking ```tsx import { useMediaStore, useMediaValue } from '@vjs-10/react-media-store'; import { MouseEvent, useRef } from 'react'; function ProgressBar() { const store = useMediaStore(); const currentTime = useMediaValue(store.currentTime); const duration = useMediaValue(store.duration); const barRef = useRef(null); const percentage = (currentTime / duration) * 100; const handleClick = (e: MouseEvent) => { if (!barRef.current) return; const rect = barRef.current.getBoundingClientRect(); const x = e.clientX - rect.left; const clickedPercentage = x / rect.width; const newTime = clickedPercentage * duration; store.currentTime.set(newTime); }; return (
); } ``` ### Time Display ```tsx import { useTimeState } from '@vjs-10/react-media-store'; function formatTime(seconds: number): string { const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${mins}:${secs.toString().padStart(2, '0')}`; } function TimeDisplay() { const { currentTime, duration } = useTimeState(); return (
{formatTime(currentTime)} / {formatTime(duration)}
); } ``` ### Volume Slider ```tsx import { VolumeHighIcon, VolumeOffIcon } from '@vjs-10/react-icons'; import { useVolumeState } from '@vjs-10/react-media-store'; function VolumeSlider() { const { volume, muted, setVolume, toggleMute } = useVolumeState(); return (
{ const newVolume = Number.parseFloat(e.target.value); setVolume(newVolume); if (muted && newVolume > 0) { toggleMute(); // Unmute when adjusting volume } }} />
); } ``` ### Fullscreen Button ```tsx import { FullscreenEnterIcon, FullscreenExitIcon } from '@vjs-10/react-icons'; import { useMediaState, useMediaStore } from '@vjs-10/react-media-store'; function FullscreenButton() { const store = useMediaStore(); const fullscreen = useMediaState(store => store.fullscreen); const handleClick = () => { store.fullscreen.set(!fullscreen); }; return ( ); } ``` ### State Persistence ```tsx import { createMediaStore, MediaStoreProvider } from '@vjs-10/react-media-store'; import { useEffect, useMemo } from 'react'; function App() { const store = useMemo(() => { const store = createMediaStore(); // Restore from localStorage const savedVolume = localStorage.getItem('player-volume'); if (savedVolume) { store.volume.set(Number.parseFloat(savedVolume)); } return store; }, []); useEffect(() => { // Persist to localStorage const unsubscribe = store.volume.subscribe((volume) => { localStorage.setItem('player-volume', volume.toString()); }); return unsubscribe; }, [store]); return ( ); } ``` ## TypeScript Support Full TypeScript definitions included: ```tsx import type { MediaStore, MediaStoreState, PlaybackState, TimeState, VolumeState, } from '@vjs-10/react-media-store'; // Store type const store: MediaStore = createMediaStore(); // State types const playbackState: PlaybackState = { paused, ended, seeking }; const timeState: TimeState = { currentTime, duration, buffered }; const volumeState: VolumeState = { volume, muted }; ``` ## Package Dependencies - **Dependencies:** `@vjs-10/media-store` - Core state management - **Peer Dependencies:** `react` >=16.8.0 - **Used by:** `@vjs-10/react` - Complete React player ## Development ```bash # Build the package pnpm build # Watch mode for development pnpm dev # Run tests pnpm test # Clean build artifacts pnpm clean ``` ## Related Packages - **[@vjs-10/media-store](../../core/media-store)** - Core state management - **[@vjs-10/react](../react)** - Complete React player - **[@vjs-10/react-media-elements](../react-media-elements)** - React media components - **[@vjs-10/html-media-store](../../html/html-media-store)** - HTML equivalent ## License Apache-2.0