Next.js中使用react-player的seekTo方法报错:seekTo is not a function
解决Next.js中ReactPlayer调用seekTo时报错"seekTo is not a function"的问题
问题根源
- 使用Next.js的
dynamic导入ReactPlayer时,默认不会将ref转发到底层的ReactPlayer组件,导致playerRef.current无法获取到组件的真实实例,调用seekTo自然会报错。 - 代码中直接依赖外部
player状态进行更新,存在状态不同步的潜在问题。
解决方案
1. 配置dynamic导入时转发ref
修改ReactPlayer的导入语句,添加forwardRef: true配置,让ref穿透到实际的ReactPlayer组件:
const ReactPlayer = dynamic(() => import("react-player"), { ssr: false, forwardRef: true // 新增配置,开启ref转发 });
2. 正确调用seekTo方法
在handleSeekMouseUp中,通过playerRef.current访问组件实例,并添加空值检查避免意外报错:
const handleSeekMouseUp = (e) => { const seekValue = parseFloat(e.target.value); setPlayer(prev => ({ ...prev, seeking: false })); if (playerRef.current) { playerRef.current.seekTo(seekValue); } };
3. 使用函数式更新避免状态不同步
所有状态更新操作改用函数式更新,确保获取到最新的state值:
const handlePlayPause = () => { setPlayer(prev => ({ ...prev, playing: !prev.playing })); }; const handleMuted = () => { setPlayer(prev => ({ ...prev, muted: !prev.muted })); }; const handleSeekMouseDown = () => { setPlayer(prev => ({ ...prev, seeking: true })); }; const handleSeekChange = (e) => { setPlayer(prev => ({ ...prev, played: parseFloat(e.target.value) })); };
完整修改后的代码
import { useRef, useState } from "react"; import dynamic from "next/dynamic"; const ReactPlayer = dynamic(() => import("react-player"), { ssr: false, forwardRef: true }); const Player = ({url}) => { const playerRef = useRef(); const [player, setPlayer] = useState({ playing: true, muted: true, played: 0, loaded: 0, duration: 0, seeking: false }); const handlePlayPause = () => { setPlayer(prev => ({ ...prev, playing: !prev.playing })); }; const handleMuted = () => { setPlayer(prev => ({ ...prev, muted: !prev.muted })); }; const handleSeekMouseDown = () => { setPlayer(prev => ({ ...prev, seeking: true })); }; const handleSeekChange = (e) => { setPlayer(prev => ({ ...prev, played: parseFloat(e.target.value) })); }; const handleSeekMouseUp = (e) => { const seekValue = parseFloat(e.target.value); setPlayer(prev => ({ ...prev, seeking: false })); if (playerRef.current) { playerRef.current.seekTo(seekValue); } }; const handleProgress = (state) => { if (!player.seeking) { setPlayer(state); } }; return ( <div className={`relative justify-center content-center w-full`}> <ReactPlayer ref={playerRef} className="absolute rounded" width="100%" height="100%" url={url} volume={1} playIcon={<></>} playing={player.playing} loop={true} muted={player.muted} onProgress={handleProgress} /> <div className="absolute w-full h-full" onClick={handlePlayPause} /> <div> <input type="range" min={0} max={0.999999} step="any" value={player.played} onMouseDown={handleSeekMouseDown} onChange={handleSeekChange} onMouseUp={handleSeekMouseUp} /> </div> </div> ); }; export default Player;
内容的提问来源于stack exchange,提问作者MiMi
相关产品推荐
相关产品推荐

