如何在Remix中更新audio标签状态?已试useRef及key属性无效
在Remix中修改Audio src的可行方案
结合useRef强制刷新音频资源
Remix的服务端渲染特性会让单纯修改ref的src无法触发资源重新加载,必须手动调用load()方法:import { useRef, useEffect } from 'react'; export default function AudioPlayer() { const audioRef = useRef(null); // 这里可以替换成从props或Remix loader获取的动态地址 const currentAudioSrc = "/new-audio.mp3"; useEffect(() => { if (!audioRef.current) return; audioRef.current.src = currentAudioSrc; audioRef.current.load(); // 关键步骤:强制加载新的音频资源 // 若需要自动播放,可添加下面一行(注意浏览器自动播放限制) // audioRef.current.play().catch(err => console.error(err)); }, [currentAudioSrc]); return <audio ref={audioRef} controls />; }用key属性配合服务端数据触发组件重挂载
如果音频地址是通过Remix的loader从服务端获取的,给audio元素设置和src绑定的唯一key,每次src更新时自动触发组件重新挂载,确保加载新资源:import { useLoaderData } from '@remix-run/react'; export async function loader() { // 模拟从服务端获取音频地址 return { audioSrc: "/server-fetched-audio.mp3" }; } export default function AudioPlayer() { const { audioSrc } = useLoaderData(); // 用audioSrc作为key,每次地址变化就重新创建audio元素 return <audio key={audioSrc} src={audioSrc} controls />; }规避SSR hydration的状态不一致问题
因为Remix是服务端渲染框架,客户端hydration阶段可能出现操作audio元素的异常,可先判断是否在客户端环境再执行操作:import { useRef, useEffect, useState } from 'react'; export default function AudioPlayer({ src }) { const audioRef = useRef(null); const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); // 标记当前处于客户端环境 }, []); useEffect(() => { if (!isClient || !audioRef.current) return; audioRef.current.src = src; audioRef.current.load(); }, [isClient, src]); // 客户端环境再渲染audio元素,避免SSR时的问题 return isClient ? <audio ref={audioRef} controls /> : null; }
内容的提问来源于stack exchange,提问作者BryceAB
相关产品推荐
相关产品推荐

