我有一个供学生使用的单词库应用程序,它可以播放这样编码的单词的音频:
import { IconButton } from "@chakra-ui/button";
import { useEffect, useState } from "react";
import { HiSpeakerWave } from "react-icons/hi2";
const useAudio = (url: string) => {
const [audio] = useState(new Audio(url));
const [playing, setPlaying] = useState(false);
const toggle = () => setPlaying(!playing);
useEffect(() => {
playing ? audio.play() : audio.pause();
}, [playing]);
useEffect(() => {
audio.addEventListener("ended", () => setPlaying(false));
return () => {
audio.removeEventListener("ended", () => setPlaying(false));
};
}, []);
return [playing, toggle];
};
interface Prop {
url: string;
}
const Player = ({ url }: Prop) => {
const [playing, toggle] = useAudio(url);
return (
<IconButton
size={"sm"}
colorScheme="teal"
aria-label="Play Audio"
borderRadius={"full"}
icon={<HiSpeakerWave />}
onClick={toggle}
/>
);
};
export default Player;
我不希望获取所有音频,因为用户永远不会在一个会话中播放所有音频。我需要对此进行哪些更改才能使其变得懒惰?仅当用户单击播放时才加载。我想到了某种方法将组件包装在点击中,然后返回加载并播放实际音频的组件。
我想到了这种通过状态设置音频 URL 的方法。这不会给我错误并播放音频。
const useAudio = (url: string) => {
const [audio, setAudio] = useState(new Audio(url));
const [playing, setPlaying] = useState(false);
const toggle = () => setPlaying(!playing);
useEffect(() => {
if (url.length) {
setAudio(new Audio(url));
}
}, [url]);
useEffect(() => {
playing ? audio.play() : audio.pause();
}, [playing]);
useEffect(() => {
audio.addEventListener("ended", () => setPlaying(false));
return () => {
audio.removeEventListener("ended", () => setPlaying(false));
};
}, []);
return [playing, toggle];
};
const Player = ({ url }: Prop) => {
const [_url, setUrl] = useState("");
const [playing, toggle] = useAudio(_url);
const handleClick = () => {
setUrl(url);
};
useEffect(() => {
if (_url.length) {
setTimeout(() => {
toggle();
}, 1000);
}
}, [_url]);
return (
<IconButton
size={"sm"}
colorScheme="teal"
aria-label="Play Audio"
borderRadius={"full"}
icon={<HiSpeakerWave />}
onClick={handleClick}
/>
);
};