问题描述
我目前正在尝试调整tone.js提供的Player组件的音量。
我启动了一个新的Player并利用useRef将对象的引用保存在current
中。
播放器包含网址,循环,音量等键。
在useEffect之外,我还有一些事件处理程序,它们控制play和stop方法,以及一个循环按钮,用于切换useEffect内部的循环状态。他们都工作。
我面临的问题是,每当我要调整音量时,都会调用useEffect,这会导致重新渲染。
我基本上希望能够更改所创建的Player对象中的音量的关键参数(值)。移动滑块时,反应会变大,但音量不会改变。
我只是希望她以前有人做过这个。
我之前的问题没有得到回答,最终我自己解决了。 我假设使用网络音频API的人似乎很少。
几周前我开始学习反应。
这是我的代码
import React,{ useState,useEffect,useRef} from "react";
import "./DrumMachine.css";
import Button from "./Button";
import { Player } from "tone";
import Sound from "./sound.wav";
import Poti from './Poti';
export default function DrumMachine() {
console.log("body")
const [value,setValue ] = useState(0);
const [loop,setLoop] = useState(false);
const playerRef = useRef(null);
playerRef.current = new Player(Sound).toDestination();
useEffect(() => {
console.log("useEffect")
console.log(playerRef.current.volume)
playerRef.current.loop = loop;
playerRef.current.volume = value;
},[loop,value]);
const play = () => {
playerRef.current.start();
};
const stop = () => {
playerRef.current.stop();
}
const volume = (event) => {
console.log(value)
setValue(event.target.value)
}
const loopToggle = () => {
console.log('loop')
setLoop(!loop);
}
const doSt = () => {
console.log('loop')
}
return (
<div className="machine">
<Button onClick={play}>Play</Button>
<Button onClick={stop}>Stop</Button>
<Button onClick={loopToggle}>
{loop ? 'Loop active' : 'Loop disabled'}
</Button>
<Button onClick={doSt}>
{'Do something'}
</Button>
<Button></Button>
<Button></Button>
<Button></Button>
<Button></Button>
<span className='vol-Box'>
<label htmlFor='vol' >Volume</label>
<Poti
onChange={volume}
value={value} id='volM'
name='vol'
min='0'
max='1'
step='0.1'
></Poti>
</span>
</div>
);
}
console.logs显然仅用于测试。我将在阅读文档的同时希望找到解决方案。
感谢您的帮助。
解决方法
工作叉。
好的,有几件事。
-
最小和最大音量太小,影响不大。我将分贝设置为-20和20,这足以引起注意。
-
我在组件外部声明了您的播放器,并将其作为ref初始值传递到了组件中。这不是执行此操作的唯一方法,但这是使示例正常工作的最简单方法。这使玩家变得单身。
如果您需要多个DrumMachine
组件。我建议在其自己的组件中创建一个播放器,并传递函数以将其更新为控件组件。这将使您的控件组件可以在不同的按钮按下时重新呈现,但是您的播放器则不能,并且您可以根据需要添加任意数量的