我创建了以下钩子来在反应中播放音频:
"use client";
import { useEffect, useState } from "react";
export const
useAudio = (url: string) => {
const [audio, setAudio] = useState<HTMLAudioElement | null>(null);
const [playing, setPlaying] = useState(false);
const setVolume = (volume: number) => {
if (audio) audio.volume = volume;
console.log(audio);
};
const toggle = () => {
setPlaying(!playing);
console.log(audio);
};
useEffect(() => {
playing ? audio?.play() : audio?.pause();
}, [playing]);
useEffect(() => {
audio?.addEventListener("ended", () => audio?.play());
}, [audio]);
useEffect(() => {
setAudio(new Audio(url));
return () => {
audio?.removeEventListener("ended", () => audio.play());
};
}, []);
return { playing, toggle, setVolume };
};
当我在切换函数内控制台记录音频元素时,我得到了正确的元素,但在 setVolume 中它始终为 null。
我在事件监听器 mouseMove 中设置音量,如下所示:
document.addEventListener("mousemove", function (e) {
let element = document.getElementById("follow");
let left = e.pageX;
let top = e.pageY;
element!.style.left = left + "px";
element!.style.top = top + "px";
const distance = Math.sqrt(
Math.pow(left - devPosition.current.x, 2) +
Math.pow(top - devPosition.current.y, 2)
);
setVolume(1 - distance / diagonal.current);
});
是否会因为我在此类侦听器内调用 setVolume 而发生这种情况?如果是这样,我该怎么办?
您直接设置
audio.volume
,但您需要使用setAudio
功能,尝试这样的操作:
const setVolume = (volume: number) => {
if (audio) {
setAudio(p => ({ ...p, volume }))
}
};
请记住,
console.log
后面的setAudio
不会立即显示您的更改: