我从React开始,花了几个小时解决这个问题。我已经设法播放声音(还没有键盘,但是稍后会出现问题),但是我无法获得声音名称(Drumpad组件中的padId)在#display(DrumMachine组件中)中显示。
我可以在一个组件中完成此操作,但是我知道将代码划分为较小的部分很重要。所以我想用这种方式(或者我应该把它做得更小?)。我尝试通过道具传递它,但是做错了。在评论中,这是我最后的尝试
import React from 'react';
import './DrumMachine.scss';
const Pads = [
[
{padId: "ching_gamelan", padKey: "Q", padUrl: "/sounds/ching_gamelan.mp3"},
{padId: "ching_gamelan2", padKey: "W", padUrl: "/sounds/ching_gamelan2.mp3"},
{padId: "hit_stick", padKey: "E", padUrl: "/sounds/hit_stick.mp3"}
],
[
{padId: "karimba", padKey: "A", padUrl: "/sounds/karimba.mp3"},
{padId: "pan_pipe", padKey: "S", padUrl: "/sounds/pan_pipe.mp3"},
{padId: "synthesiser", padKey: "D", padUrl: "/sounds/synthesiser.mp3"}
],
[
{padId: "tifu", padKey: "Z", padUrl: "/sounds/tifu.mp3"},
{padId: "tifutifu", padKey: "X", padUrl: "/sounds/tifutifu.mp3"},
{padId: "ukulele", padKey: "C", padUrl: "/sounds/ukulele.mp3"}
]
];
class Drumpad extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
playSound() {
const sound = document.getElementById(this.props.padKey);
sound.currentTime = 0;
sound.play();
}
activePad() {
const active = document.getElementById(this.props.padId);
active.className = "drum-pad active";
setTimeout(() => (active.className = "drum-pad"), 100);
// this.props.getSoundName(this.props.padId); - not working
}
handleClick(event) {
this.playSound();
this.activePad();
};
render() {
return (
<div className="drum-pad" id={this.props.padId} onClick={this.handleClick}>
<audio className="clip" id={this.props.padKey}>
<source src={this.props.padUrl} type="audio/mp3" />
</audio>
<span>{this.props.padKey}</span>
</div>
);
}
}
class DrumMachine extends React.Component {
constructor(props) {
super(props);
this.state = {
currentSoundName: '',
currentSoundUrl: ''
};
this.getSoundName = this.getSoundName.bind(this);
}
getSoundName(name) {
this.setState({
currentSoundName: name
});
} // this.props.getSoundName(this.props.padId); - not working
render() {
const DrumGroups = Pads.map(function(a) {
return (
<div className="drum-group">
{a.map(i => <Drumpad padId={i.padId} padKey={i.padKey} padUrl={i.padUrl} /*getSound={this.props.getSoundName} - not working*/ />)}
</div>
);
});
const Zapsplat = (
<span className="zapsplat">Sound effects obtained from https://www.zapsplat.com</span>
);
return (
<div className="container">
{Zapsplat}
<div id="drum-machine">
<span id="display">{this.state.currentSoundName}</span>
<span id="drumpads">{DrumGroups}</span>
</div>
</div>
);
}
}
export default DrumMachine;
总结一下。我想在单击一个打击垫后获取padId并将其传递到DrumMachine的状态“ currentSoundName”中。
提前谢谢
答案 0 :(得分:1)
嗯,我距离我是如此之近。谢谢@mfakhrusy的帮助。
还缺少一件事,但是感谢this topic在stackoverflow上的发现,现在它可以正常运行了
const DrumGroups = Pads.map((a) => {
return (
<div className="drum-group">
{a.map(i => <Drumpad padId={i.padId} padKey={i.padKey} padUrl={i.padUrl} keyCode={i.keyCode} getSound={this.getSoundName} />)}
</div>
);
});
编辑:根据@mfakhrusy的建议,使用箭头功能。
答案 1 :(得分:0)
<div className="drum-group">
{a.map(i => <Drumpad padId={i.padId} padKey={i.padKey} padUrl={i.padUrl} getSound={this.getSoundName} />)}
</div>
已编辑,只需将方法传递给getSound
道具,然后在Drumpad组件上的activePad
方法中访问它即可:
您的activePad应该是这样的
activePad() {
const active = document.getElementById(this.props.padId);
active.className = "drum-pad active";
setTimeout(() => (active.className = "drum-pad"), 100);
this.props.getSound(this.props.padId);
}