next.js React在事件中使用钩子

laik7k3q  于 2023-10-18  发布在  React
关注(0)|答案(1)|浏览(151)

我创建了以下钩子来在react中播放音频:

  1. "use client";
  2. import { useEffect, useState } from "react";
  3. export const
  4. useAudio = (url: string) => {
  5. const [audio, setAudio] = useState<HTMLAudioElement | null>(null);
  6. const [playing, setPlaying] = useState(false);
  7. const setVolume = (volume: number) => {
  8. if (audio) audio.volume = volume;
  9. console.log(audio);
  10. };
  11. const toggle = () => {
  12. setPlaying(!playing);
  13. console.log(audio);
  14. };
  15. useEffect(() => {
  16. playing ? audio?.play() : audio?.pause();
  17. }, [playing]);
  18. useEffect(() => {
  19. audio?.addEventListener("ended", () => audio?.play());
  20. }, [audio]);
  21. useEffect(() => {
  22. setAudio(new Audio(url));
  23. return () => {
  24. audio?.removeEventListener("ended", () => audio.play());
  25. };
  26. }, []);
  27. return { playing, toggle, setVolume };
  28. };

当我在toggle函数中控制台记录audio元素时,我得到了正确的元素,但在setVolume中它总是null。
我在一个事件管理器鼠标中设置音量,像这样移动:

  1. document.addEventListener("mousemove", function (e) {
  2. let element = document.getElementById("follow");
  3. let left = e.pageX;
  4. let top = e.pageY;
  5. element!.style.left = left + "px";
  6. element!.style.top = top + "px";
  7. const distance = Math.sqrt(
  8. Math.pow(left - devPosition.current.x, 2) +
  9. Math.pow(top - devPosition.current.y, 2)
  10. );
  11. setVolume(1 - distance / diagonal.current);
  12. });

这会因为我在这样的侦听器中调用setVolume而发生吗?如果是这样,我能做些什么呢?

hts6caw3

hts6caw31#

我试过你的useAudio钩子,我认为钩子没有什么问题。
例如,像这样的组件按预期工作,不会产生任何错误。

  1. "use client";
  2. import { useEffect } from "react";
  3. import { useAudio } from "./audioHook"
  4. export default function Home() {
  5. const controls = useAudio('./horse.mp3');
  6. useEffect(() => {
  7. console.log(controls.playing);
  8. }, [controls]);
  9. const workWithAudio = () => {
  10. controls.toggle();
  11. };
  12. const changeVolume = () => {
  13. controls.setVolume(0.2);
  14. };
  15. return (
  16. <main>
  17. <button onClick={workWithAudio}>
  18. The toggle button
  19. </button>
  20. <button onClick={changeVolume}>
  21. The volume button
  22. </button>
  23. </main>
  24. )
  25. }

您处理侦听器的方式可能存在问题。如果我理解正确的话(例如看这里How to add a 'mousemove' event listener to a component Cursor which is moved with the cursor pointer in ReactJS?),在React组件中添加侦听器的首选方法是将其添加到DOM节点,如下所示:

  1. "use client";
  2. import { useAudio } from "./audioHook"
  3. export default function Home() {
  4. const controls = useAudio('./horse.mp3');
  5. const handleMouseMove = (e: MouseEvent) => {
  6. let element = document.getElementById("follow");
  7. let left = e.pageX;
  8. let top = e.pageY;
  9. element!.style.left = left + "px";
  10. element!.style.top = top + "px";
  11. // const distance = Math.sqrt(
  12. // Math.pow(left - devPosition.current.x, 2) +
  13. // Math.pow(top - devPosition.current.y, 2)
  14. // );
  15. controls.setVolume(0.5);
  16. }
  17. return (
  18. <main onMouseMove={handleMouseMove}>
  19. <div id="follow">TEST</div>
  20. </main>
  21. )
  22. }

我不能访问你在函数中使用的devPositiondiagonal变量,所以我必须使用一个常量,但是如果你以这种方式示例化监听器,你就可以毫无问题地设置音量。

展开查看全部

相关问题