如何在 React 功能组件中切换音频
How to toggle audio in React functional component
我正在尝试 play/stop 单击 <img />
时的音频。每个 <img />
都与不同的音频文件相关。音频应在用户不停止时循环播放。我宁愿不使用 类 组件,因为我可以使用钩子。
我的实际代码没有停止音频;不要循环它;如果我点击两次,音频就会重叠(同时发出两个声音)。
import myJSON from "./assets/myJSON.json";
export default function Card() {
const handleClick = (argument) => {
new Audio(argument.target.dataset.sound).play()
}
return (
<>
{myJSON.map((myObject, index) => {
return (
<img
src={myObject.image}
alt={myObject.name}
key={index}
onClick={handleClick}
data-sound={myObject.sound}
/>
);
})}
</>
);
}
我可以随意更改 json 或尝试不同的方法。
我已经为您创建了一个代码沙箱,您可以在此处访问:https://codesandbox.io/s/silly-hypatia-8fwun?file=/src/App.js
我创建了一个示例,说明我将如何按照这些思路处理某些事情:
请注意:数组的顺序很重要,因为我要根据索引来决定播放什么歌曲,不播放什么歌曲。您不一定非要采用这种方法。这只是一个快速而肮脏的解决方案。
import { useEffect, useState } from "react";
export default function App() {
const [musicArray] = useState([
"https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba-online-audio-converter.com_-1.wav",
"https://www2.cs.uic.edu/~i101/SoundFiles/BabyElephantWalk60.wav"
]);
const [data, setData] = useState([]);
useEffect(() => {
const musicData = musicArray.map((sound) => {
return { audio: new Audio(sound), play: false };
});
setData(musicData);
}, [musicArray]);
const playSound = (index) => {
setData((arr) =>
arr.map((sound, i) => {
if (i === index) {
sound.audio.play();
return { ...sound, play: true };
}
sound.audio.pause();
return { ...sound, play: false };
})
);
};
useEffect(() => {
console.log(data);
}, [data]);
const stopSound = (index) => {
setData((arr) =>
arr.map((sound, i) => {
if (i === index) {
sound.audio.pause();
return { ...sound, play: false };
}
return { ...sound, play: false };
})
);
};
return (
<div className="App">
{data.map((sound, i) => {
return (
<>
{sound.play ? (
<button onClick={() => stopSound(i)}>pause</button>
) : (
<button onClick={() => playSound(i)}>play</button>
)}
</>
);
})}
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
我正在尝试 play/stop 单击 <img />
时的音频。每个 <img />
都与不同的音频文件相关。音频应在用户不停止时循环播放。我宁愿不使用 类 组件,因为我可以使用钩子。
我的实际代码没有停止音频;不要循环它;如果我点击两次,音频就会重叠(同时发出两个声音)。
import myJSON from "./assets/myJSON.json";
export default function Card() {
const handleClick = (argument) => {
new Audio(argument.target.dataset.sound).play()
}
return (
<>
{myJSON.map((myObject, index) => {
return (
<img
src={myObject.image}
alt={myObject.name}
key={index}
onClick={handleClick}
data-sound={myObject.sound}
/>
);
})}
</>
);
}
我可以随意更改 json 或尝试不同的方法。
我已经为您创建了一个代码沙箱,您可以在此处访问:https://codesandbox.io/s/silly-hypatia-8fwun?file=/src/App.js
我创建了一个示例,说明我将如何按照这些思路处理某些事情:
请注意:数组的顺序很重要,因为我要根据索引来决定播放什么歌曲,不播放什么歌曲。您不一定非要采用这种方法。这只是一个快速而肮脏的解决方案。
import { useEffect, useState } from "react";
export default function App() {
const [musicArray] = useState([
"https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba-online-audio-converter.com_-1.wav",
"https://www2.cs.uic.edu/~i101/SoundFiles/BabyElephantWalk60.wav"
]);
const [data, setData] = useState([]);
useEffect(() => {
const musicData = musicArray.map((sound) => {
return { audio: new Audio(sound), play: false };
});
setData(musicData);
}, [musicArray]);
const playSound = (index) => {
setData((arr) =>
arr.map((sound, i) => {
if (i === index) {
sound.audio.play();
return { ...sound, play: true };
}
sound.audio.pause();
return { ...sound, play: false };
})
);
};
useEffect(() => {
console.log(data);
}, [data]);
const stopSound = (index) => {
setData((arr) =>
arr.map((sound, i) => {
if (i === index) {
sound.audio.pause();
return { ...sound, play: false };
}
return { ...sound, play: false };
})
);
};
return (
<div className="App">
{data.map((sound, i) => {
return (
<>
{sound.play ? (
<button onClick={() => stopSound(i)}>pause</button>
) : (
<button onClick={() => playSound(i)}>play</button>
)}
</>
);
})}
<h2>Start editing to see some magic happen!</h2>
</div>
);
}