所以我正在构建一个鼓垫类型的应用程序,除了这个之外,几乎所有东西都可以正常工作。
编辑:把整个东西放在codesandbox上,如果有人想看的话:codesandbox.io/s/sleepy-darwin-jc9b5?file=/src/App.js
const [index, setIndex] = useState(0);
const [text, setText] = useState("");
const [theSound] = useSound(drumBank[index].url)
function playThis(num) {
setIndex(num)
}
useEffect(()=>{
if (index !== null) {
setText(drumBank[index].id);
theSound(index);
console.log(index)
}
}, [index])
当我按下按钮时,索引会更改为与该按钮关联的值,然后 useEffect 挂钩会播放该数组中的声音index。但是,当我多次按下同一个按钮时,它只会播放一次,因为 useState 不会在index更改为相同的值。
我希望能够多次按下同一个按钮并使应用程序重新渲染,因此每次按下按钮时 useEffect 都会运行。谁能帮助我如何做到这一点?
这是我可以从你的沙箱中得到的结果。
-
根据每个文档useSound
只是一种声音,因此当尝试将索引更新到音库以通过 React 状态使用时,播放的声音将始终至少延迟一个渲染周期。我建议创建一个新的自定义 hook 来封装您的 9 种鼓声。
useDrumBank
使用鼓组数组并将 9 个鼓声音实例化到一个数组中。
const useDrumBank = (drumbank) => {
const [drum0] = useSound(drumbank[0].url);
const [drum1] = useSound(drumbank[1].url);
const [drum2] = useSound(drumbank[2].url);
const [drum3] = useSound(drumbank[3].url);
const [drum4] = useSound(drumbank[4].url);
const [drum5] = useSound(drumbank[5].url);
const [drum6] = useSound(drumbank[6].url);
const [drum7] = useSound(drumbank[7].url);
const [drum8] = useSound(drumbank[8].url);
return [drum0, drum1, drum2, drum3, drum4, drum5, drum6, drum7, drum8];
};
-
更新组件逻辑以传递drumBank
数组到新的自定义挂钩。
const sounds = useDrumBank(drumBank);
这是完整的代码:
function App() {
useEffect(() => {
document.addEventListener("keypress", key);
return () => document.removeEventListener("keypress", key);
}, []);
const [text, setText] = useState("");
const sounds = useDrumBank(drumBank);
function playThis(index) {
drumBank[index]?.id && setText(drumBank[index].id);
sounds[index]();
}
function key(e) {
const index = drumBank.findIndex((drum) => drum.keyTrigger === e.key);
index !== -1 && playThis(index);
}
return (
<div id="drum-machine" className="drumpad-container">
<div id="display" className="drumpad-display">
<p>{text}</p>
</div>
<button className="drum-pad" id="drum-pad-1" onClick={() => playThis(0)}>
Q
</button>
<button className="drum-pad" id="drum-pad-2" onClick={() => playThis(1)}>
W
</button>
<button className="drum-pad" id="drum-pad-3" onClick={() => playThis(2)}>
E
</button>
<button className="drum-pad" id="drum-pad-4" onClick={() => playThis(3)}>
A
</button>
<button className="drum-pad" id="drum-pad-5" onClick={() => playThis(4)}>
S
</button>
<button className="drum-pad" id="drum-pad-6" onClick={() => playThis(5)}>
D
</button>
<button className="drum-pad" id="drum-pad-7" onClick={() => playThis(6)}>
Z
</button>
<button className="drum-pad" id="drum-pad-8" onClick={() => playThis(7)}>
X
</button>
<button className="drum-pad" id="drum-pad-9" onClick={() => playThis(8)}>
C
</button>
</div>
);
}
Demo
使用说明
加载后立即没有声音 https://www.npmjs.com/package/use-sound#no-sounds-immediately-after-load
为了用户的利益,浏览器不允许网站发出声音
直到用户与它们交互(例如,通过单击
某物)。在用户单击、敲击或点击之前不会产生声音
触发某事。
让按键持续工作似乎是一个问题,我并没有立即想到解决方案,但至少在这一点上按钮点击工作并且声音同步播放。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)