遍历组件的所有实例,记录每个状态

时间:2019-03-25 18:18:34

标签: javascript html reactjs

我正在使用ReactJS构建一个简单的鼓机应用程序,可以使用一些帮助来理解如何在输出每个实例的状态时遍历组件的所有实例。

应用程序用户界面显示16列按钮,每列包含4个唯一的鼓行。有一个“ SixteenthNote.js”组件,该组件实质上在包含每个“ Drum.js”实例的列上。在“ DrumMachine.js”模块中,我将输出“ SixteenthNote.js” 16次以显示一种完整的音乐。当您单击鼓按钮时,该鼓的值将被推入SixththNote的状态数组。这一切都按预期进行。

最后一步是创建一个“ Play.js”组件,单击该组件将循环遍历所有SixththNote实例并输出每个实例的状态。

这是“ 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>
    )
  }
}

1 个答案:

答案 0 :(得分:2)

您将需要在DrumMachine组件中包含有关activeDrums的信息。 这意味着:

在DrumMachine组件中,就像在SixteenthNote.js中一样,创建状态activeDrums。您还需要将updateActiveDrumsArray函数放到drumMachine组件中。

然后将该函数传递给您的SixteenthNote组件,例如:

<SixteenthNote columnClassName="drum__column" key={index} drumOptions={this.state.drumOptions} onDrumsClick={this.updateActiveDrumsArray} />

这样做后,您可以通过道具访问该功能。因此,在您的SixththNote组件中,其外观应为:

<Drum buttonClassName="drum__button" audioClassName="drum__audio" type={button.type} file={button.file} key={index} onClick={() => this.props.onDrumsClick(button.type)}/>

(不要忘记删除不必要的代码。)

有了这个,您就可以在DrumMachine中将activeDrums状态设置为包含所有活动鼓的状态。然后,您可以将该状态发送到您的播放组件并在其中执行播放操作。