我正在使用 ReactJS 构建一个简单的鼓机应用程序,并且可以使用一些帮助来理解如何在输出每个实例的状态时循环遍历组件的所有实例。
应用程序 UI 显示 16 列按钮,每列包含 4 个独特的鼓行。有一个“SixteenthNote.js”组件,它本质上位于包含每个“Drum.js”实例的列上。在“DrumMachine.js”模块中,我输出“SixteenthNote.js”16 次以显示完整的音乐小节。当您单击鼓按钮时,该鼓的值将被插入 SixteenthNote 的状态数组中。这一切都按预期进行。
最后一部分是创建一个“Play.js”组件,单击该组件时,它将循环遍历所有 SixteenthNote 实例并输出每个实例的状态。
这是“DrumMachine.js”模块
class DrumMachine extends Component {
constructor(props) {
super(props);
this.buildKit = this.buildColumns.bind(this);
this.buildLabels = this.buildLabels.bind(this);
this.buildAudio = this.buildAudio.bind(this);
this.state = {
placeArray: Array(16).fill(),
drumOptions: [
{type: 'crash', file: crash, title: 'Crash'},
{type: 'kick', file: kick, title: 'Kick'},
{type: 'snare', file: snare, title: 'Snare'},
{type: 'snare-2', file: snare2, title: 'Snare'}
]
}
}
buildLabels() {
const labelList = this.state.drumOptions.map((sound, index) => {
return <SoundLabel title={sound.title} className="drum__label" key={index} />
})
return labelList;
}
buildColumns() {
const buttonList = this.state.placeArray.map((object, index) => {
return <SixteenthNote columnClassName="drum__column" key={index} drumOptions={this.state.drumOptions}/>
});
return buttonList;
}
buildAudio() {
const audioList = this.state.drumOptions.map((audio, index) => {
return <Audio source={audio.file} drum={audio.type} key={index}/>
})
return audioList;
}
render() {
return (
<div>
<div className={this.props.className}>
<div className="label-wrapper">
{this.buildLabels()}
</div>
<div className="drum-wrapper">
{this.buildColumns()}
</div>
</div>
<div className="audio-wrapper">
{this.buildAudio()}
</div>
</div>
)
}
}
这是“SixteenthNote.js”模块
class SixteenthNote extends Component {
constructor(props) {
super(props);
this.buildColumn= this.buildColumn.bind(this);
this.buildDrumOptions = this.buildDrumOptions.bind(this);
this.updateActiveDrumsArray = this.updateActiveDrumsArray.bind(this);
this.state = {
activeDrums: []
}
}
buildDrumOptions() {
return this.props.drumOptions;
}
updateActiveDrumsArray(type) {
let array = this.state.activeDrums;
array.push(type);
this.setState({activeDrums: array});
}
buildColumn() {
const placeArray = this.buildDrumOptions().map((button, index) => {
return <Drum buttonClassName="drum__button" audioClassName="drum__audio" type={button.type} file={button.file} key={index} onClick={() => this.updateActiveDrumsArray(button.type)}/>
})
return placeArray;
}
render() {
return (
<div className={this.props.columnClassName}>
{this.buildColumn()}
</div>
)
}
}
这是“Drum.js”模块
class Drum extends Component {
constructor(props) {
super(props);
this.clickFunction = this.clickFunction.bind(this);
this.state = {
clicked: false
}
}
drumHit(e) {
document.querySelector(`.audio[data-drum=${this.props.type}]`).play();
this.setState({clicked:true});
}
clickFunction(e) {
this.state.clicked === false ? this.drumHit(e) : this.setState({clicked:false})
}
render() {
const drumType = this.props.type;
const drumFile = this.props.file;
const buttonClasses = `${this.props.buttonClassName} drum-clicked--${this.state.clicked}`
return (
<div onClick={this.props.onClick}>
<button className={buttonClasses} data-type={drumType} onClick={this.clickFunction}></button>
</div>
)
}
}
最佳答案
您需要在 DrumMachine 组件中包含有关 activeDrums 的信息。 这意味着:
在 DrumMachine 组件中,您可以像在 SixteenthNote.js 中一样创建状态 activeDrums
。您还需要将 updateActiveDrumsArray 函数放入鼓机器组件中。
然后将此函数传递给 SixteenthNote 组件,如下所示:
<SixteenthNote columnClassName="drum__column" key={index} drumOptions={this.state.drumOptions} onDrumsClick={this.updateActiveDrumsArray} />
完成此操作后,您可以通过 props 访问该功能。因此,在您的 SixteenthNote 组件中,它应该如下所示:
<Drum buttonClassName="drum__button" audioClassName="drum__audio" type={button.type} file={button.file} key={index} onClick={() => this.props.onDrumsClick(button.type)}/>
(不要忘记删除不必要的代码。)
这样,您就可以在 DrumMachine 中获得包含所有事件鼓的 activeDrums 状态。然后您可以将此状态发送到播放组件并在那里执行播放操作。
关于javascript - 循环组件的所有实例,记录每个状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55344211/