尝试在数组中使用 React 的 useRef 来获取音频的持续时间
Trying to us React's useRef in an array to grab an audio' duration
当我 运行 我的反应代码时,我目前收到错误 Cannot read property 'addEventListener' of undefined
。该代码旨在遍历包含音频文件的列表并获取音频持续时间。该应用程序正确呈现,但我在生命周期方面做错了。我认为。下面的代码
import React, { useRef, useEffect, useState } from "react"
import { Link } from "gatsby"
const Single = ({ name, tracks }) => {
const [duration, setDuration] = useState([])
const audioRef = useRef([])
function getTrackLength(track) {
track.addEventListener("loadedmetadata", function () {
setDuration(track.duration)
})
}
useEffect(() => {
audioRef.current = new Array(tracks.length)
}, [])
useEffect(() => {
if (audioRef.current.length !== 0) {
for (let i = 0; i <= audioRef.current.length; i++) {
getTrackLength(audioRef.current[i])
}
}
}, [])
return (
<>
<h2>{name}</h2>
<ul>
{tracks.map((track, i) => (
<li key={track._id}>
<div>
<strong>{track.name}</strong>
<audio
ref={el => (audioRef.current[i] = el)}
src={track.file}
controls
/>
<i>{duration}</i>
</div>
</li>
))}
</ul>
<Link to="/singles">Back</Link>
</>
)
}
export default Single
非常感谢
您有一个额外的迭代,其中包含 undefined
作为 track
:
// v not <=
for (let i = 0; i < audioRef.current.length; i++) {
getTrackLength(audioRef.current[i]);
}
您的组件应如下所示:
const Single = ({ name, tracks }) => {
const [duration, setDuration] = useState([]);
const audioRef = useRef(new Array(Number(tracks.length));
useEffect(() => {
function getTrackLength(track) {
track.addEventListener("loadedmetadata", function () {
setDuration([...duration, track.duration]);
});
}
for (let i = 0; i < audioRef.current.length; i++) {
getTrackLength(audioRef.current[i]);
}
}, []);
return (
<>
<h2>{name}</h2>
<ul>
{tracks.map((track, i) => (
<li key={track._id}>
<div>
<strong>{track.name}</strong>
<audio
ref={(el) => (audioRef.current[i] = el)}
src={track.file}
controls
/>
<i>{duration[i]}</i>
</div>
</li>
))}
</ul>
<Link to="/singles">Back</Link>
</>
);
};
export default Single;
当我 运行 我的反应代码时,我目前收到错误 Cannot read property 'addEventListener' of undefined
。该代码旨在遍历包含音频文件的列表并获取音频持续时间。该应用程序正确呈现,但我在生命周期方面做错了。我认为。下面的代码
import React, { useRef, useEffect, useState } from "react"
import { Link } from "gatsby"
const Single = ({ name, tracks }) => {
const [duration, setDuration] = useState([])
const audioRef = useRef([])
function getTrackLength(track) {
track.addEventListener("loadedmetadata", function () {
setDuration(track.duration)
})
}
useEffect(() => {
audioRef.current = new Array(tracks.length)
}, [])
useEffect(() => {
if (audioRef.current.length !== 0) {
for (let i = 0; i <= audioRef.current.length; i++) {
getTrackLength(audioRef.current[i])
}
}
}, [])
return (
<>
<h2>{name}</h2>
<ul>
{tracks.map((track, i) => (
<li key={track._id}>
<div>
<strong>{track.name}</strong>
<audio
ref={el => (audioRef.current[i] = el)}
src={track.file}
controls
/>
<i>{duration}</i>
</div>
</li>
))}
</ul>
<Link to="/singles">Back</Link>
</>
)
}
export default Single
非常感谢
您有一个额外的迭代,其中包含 undefined
作为 track
:
// v not <=
for (let i = 0; i < audioRef.current.length; i++) {
getTrackLength(audioRef.current[i]);
}
您的组件应如下所示:
const Single = ({ name, tracks }) => {
const [duration, setDuration] = useState([]);
const audioRef = useRef(new Array(Number(tracks.length));
useEffect(() => {
function getTrackLength(track) {
track.addEventListener("loadedmetadata", function () {
setDuration([...duration, track.duration]);
});
}
for (let i = 0; i < audioRef.current.length; i++) {
getTrackLength(audioRef.current[i]);
}
}, []);
return (
<>
<h2>{name}</h2>
<ul>
{tracks.map((track, i) => (
<li key={track._id}>
<div>
<strong>{track.name}</strong>
<audio
ref={(el) => (audioRef.current[i] = el)}
src={track.file}
controls
/>
<i>{duration[i]}</i>
</div>
</li>
))}
</ul>
<Link to="/singles">Back</Link>
</>
);
};
export default Single;