javascript - 循环组件的所有实例,记录每个状态

标签 javascript html reactjs

我正在使用 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/

相关文章:

javascript - 使用 lodash 在 javascript 中查找两组数据之间的匹配

javascript - 将 Node.js 请求包装到 Promise 和管道中

javascript - 将 div 向下移动一次超过某个点

javascript - React Redux 和 react-router-dom

javascript - mapStateToProps 从 reducer 返回未定义的状态

javascript - bootstrap 4 我的 slider 无法正常工作

javascript - 检测固定元素何时返回其原始位置

html - 重新排列页面上的默认列(-webkit-column,-moz-column)顺序?

javascript - 使用 id 'user' +i 的复选框切换 id 'checkbox' +i 的属性

ReactJs 0.14 - 不变违规 : Objects are not valid as a React child