将数据从孩子传递给父母

时间:2019-02-17 21:36:17

标签: reactjs

我从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”中。

提前谢谢

2 个答案:

答案 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);
}