问题描述
我有一个组件,它实例化 Tone.js 库中的一些类(例如音频播放器和过滤器),并定义了一些作用于这些对象的函数,这些函数用作一组 UI 渲染按钮中的回调(见下方相关代码)。
其中两个按钮应该使用 useState hook(在 is3D
函数中)切换布尔状态 updateSpatial
以启用/禁用这些按钮之一。但是,此更新显然会导致组件完全重新渲染,从而重新实例化我的类,这会阻止已定义的函数在之后工作。
相比之下,我还尝试了 useRef hook,它允许在不重新渲染的情况下更新 is3D
,但按钮的禁用状态不会更新,因为组件不会重新渲染。
有没有适合这种情况的模式?我的下一次尝试包括使用 HOC、Context 或 Redux,但我不确定这是最直接的。谢谢!
import React,{useState,useEffect,Fragment} from 'react'
import { Player,Destination} from "tone";
const Eagles = () => {
const [is3D,setIs3D] = useState(false);
useEffect(() => {
// connect players to destination,ready to play
connectBase();
});
// Instantiating players
const player1= new Player({
"url": "https://myapp.s3.eu-west-3.amazonaws.com/Aguabeber.m4a","autostart": false,"onload": console.log("player 1 ready")
});
const player2 = new Player({
"url": "https://myapp.s3.eu-west-3.amazonaws.com/Aguas.m4a","onload": console.log("player 2 ready")
});
// Functions
function connectBase() {
player1.disconnect();
player1.connect(Destination);
player2.disconnect();
player2.chain(Destination);
}
function playStudio() {
player1.volume.value = 0;
player2.volume.value = -60;
}
function playCinema() {
player1.volume.value = -60;
player2.volume.value = 0;
}
function playstereo() {
player1.volume.value = 0;
player2.volume.value = -60;
updateSpatial();
}
function playmyhifi() {
player1.volume.value = -60;
player2.volume.value = 0;
updateSpatial();
}
function start() {
player1.start();
player2.start();
playstereo();
}
function stop() {
player1.stop();
player2.stop();
console.log("stop pressed")
}
// Update state to toggle button enabled`
function updateSpatial() {
setIs3D((is3D) => !is3D);
}
return (
<Fragment>
<ButtonTL onClick={start}>Play</ButtonTL>
<ButtonTR onClick={stop}>Stop</ButtonTR>
<ButtonTL2 onClick={playstereo}>Stereo</ButtonTL2>
<ButtonTR2 onClick={playmyhifi}>3D</ButtonTR2>
<ButtonLL disabled={is3D} onClick={playStudio}>Studio</ButtonLL>
<ButtonLR onClick={playCinema}>Cinema</ButtonLR>
</Fragment>
)
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)