I have this application of a word bank for students and it can play the audio for the words coded like this:
import { IconButton } from "@chakra-ui/button";
import { useEffect, useState } from "react";
import { HiSpeakerWave } from "react-icons/hi2";
const useAudio = (url: string) => {
const = 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;
I don’t want all the audio to be fetched because the user will never play them all in one session. What changes do I need to make to this to make it lazy? For it to only load when a user clicks play. I think of someone way to wrap the component inside of a click and then return a component that loads and plays the actual audio.
2
Answers
I thought of this approach where I set the URL for the audio through a state. This doesn't give me errors and plays the audio.
I have done the same lazy loading (audio player) for one of my clients.
Let me give suggestion in short which will help you (If not do let me know) – Use Redux and dispatch the action on click of every play button.
Note: action should take an
arg
ofurl
.