在JSX中使用map生成Audio组件时出现audioRef未定义问题
React中通过map生成
我尝试用map批量生成
import React, { useState, useRef, createRef } from 'react'; const audios = [{ src: '/fire.mp3' }, { src: '/crickets.mp3' }]; function Audio({ audioRef }) { const { src, ref } = audioRef; function handleVolumeChange(value) { ref.current.volume = value / 100; } return ( <audio ref={ref} loop> <source src={src} type="audio/mpeg" /> Your browser does not support the audio element. </audio> // `handleVolumeChange` is used here ); } export const App = ({ name }) => { const audioRefs = useRef( audios.map((audio) => ({ ...audio, ref: createRef(), })) ); return ( <> {audioRefs.current.map((audioRef, index) => ( <Audio key={audioRef.src} audio={audioRef} /> ))} </> ); };
运行时出现错误:
Cannot destructure property 'src' of 'audioRef' as it is undefined.
明明audioRefs是包含两个对象的数组:
[{…}, {…}] 0: Object ref: Object src: "/fire.mp3" <prototype>: Object 1: Object ref: Object src: "/crickets.mp3" <prototype>: Object
需求:需要通过ref控制
问题原因
父组件给<Audio>传递的props属性名是audio,但子组件Audio声明接收的参数是audioRef,两者命名不匹配,导致子组件内的audioRef为undefined,无法解构出src和ref。
修复方案
1. 统一props命名
要么修改子组件的接收参数名,要么修改父组件的传递属性名,二选一即可:
方案A:修改子组件接收参数
function Audio({ audio }) { const { src, ref } = audio; // 其余逻辑保持不变 }
方案B:修改父组件传递的属性名
// 父组件中渲染Audio时修改属性名 <Audio key={audioRef.src} audioRef={audioRef} />
2. 补充音量控制实现示例
如果需要实现音量调节功能,可以在子组件中添加滑块控件,结合ref操作audio元素:
function Audio({ audio }) { const { src, ref } = audio; const handleVolumeChange = (e) => { const volumeValue = e.target.value / 100; if (ref.current) { ref.current.volume = volumeValue; } }; return ( <div className="audio-control"> <audio ref={ref} loop> <source src={src} type="audio/mpeg" /> Your browser does not support the audio element. </audio> <input type="range" min="0" max="100" defaultValue="50" onChange={handleVolumeChange} title="调节音量" /> </div> ); }
3. 优化ref初始化方式(可选)
也可以用useRef结合useEffect来初始化ref数组,逻辑更清晰:
export const App = ({ name }) => { const audioRefs = useRef([]); useEffect(() => { // 初始化每个audio对应的ref audioRefs.current = audios.map(() => createRef()); }, []); return ( <> {audios.map((audio, index) => ( <Audio key={audio.src} audio={{ src: audio.src, ref: audioRefs.current[index] }} /> ))} </> ); };
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

