如何在react中延迟加载音频组件

问题描述 投票:0回答:1

我有一个供学生使用的单词库应用程序,它可以播放这样编码的单词的音频:

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;

我不希望获取所有音频,因为用户永远不会在一个会话中播放所有音频。我需要对此进行哪些更改才能使其变得懒惰?仅当用户单击播放时才加载。我想到了某种方法将组件包装在点击中,然后返回加载并播放实际音频的组件。

javascript reactjs audio lazy-loading
1个回答
0
投票

我想到了这种通过状态设置音频 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}
    />
  );
};


© www.soinside.com 2019 - 2024. All rights reserved.