ReactJS - 如何在 onKeyPress 和 onClick 上播放音频元素?

ReactJS - How do I play an audio element onKeyPress and onClick?

所以我正在尝试从 freeCodeCamp 构建 Drum Machine 项目,但我遇到了音频元素的这个问题。我写了下面的代码。我没有收到任何错误,但是当我用 class“鼓垫”单击 div 时,音频仍然无法播放。我知道如何在没有 audio 元素的情况下完成这项工作,但挑战需要专门使用该元素。

我仍然会尝试自己解决这个问题,如果我在其他地方找到解决方案,我会更新这个问题。

这是我的 DrumPad 组件

import React from 'react';

class DrumPad extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            name: this.props.name,
            audio: this.props.source,
            indexNr: this.props.indexNr,
            keyId: this.props.keyId
        }
        this.clickHandle = this.clickHandle.bind(this);
        this.keyPressHandle = this.keyPressHandle.bind(this);
    }


    clickHandle() {
        document.getElementById(`audio${this.state.indexNr}`).play();
    }

    keyPressHandle(event) {
        if(event.key === this.state.keyId || event.key === this.state.keyId.toLowerCase()){
            document.getElementById(`audio${this.state.indexNr}`).play();
        }
    }

    render(){
        return (
            <div className="drum-pad" id={this.name} onClick={this.clickHandle} onKeyPress={this.keyPressHandle}>
                    <h3>{this.state.keyId}</h3>
                    <audio id={`audio${this.state.indexNr}`} src={this.audio} />
            </div>
        )
    }
}

export default DrumPad; 

这是我的键盘组件

import DrumPad from "./DrumpPad";

const Keyboard = (props) => {
    return <div className="column1">
        { 
            soundsArr.map((sound, index) => <DrumPad key={index} indexNr={index} name={sound.name} source={sound.source} keyId={sound.keyId} />) 
        }
    </div>
}

export default Keyboard;


const soundsArr = [
    {
      name: "Drum0", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "Q"
    },
    {
      name: "Drum1", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "W"
    },
    {
      name: "Drum2", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "E"
    },
    {
      name: "Drum3", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "A"
    },
    {
      name: "Drum4", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "S"
    },
    {
      name: "Drum5", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "D"
    },
    {
      name: "Drum6", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "Z"
    },
    {
      name: "Drum7", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "X"
    },
    {
      name: "Drum8", 
      source: "https://s3.amazonaws.com/freecodecamp/drums/Heater-6.mp3",
      keyId: "C"
    }
  ];
很多。但这是我编辑代码的方式。


  • DrumPad 组件中,您将所有道具添加到状态。这不是必需的,因为您没有更改任何值,因此最好从 Class to a Function 组件转换组件。
  • 您向 DrumPad 组件中的父 div 元素添加了一个 onKeyPress 事件。那永远不会 运行 因为元素无法聚焦。因此,您应该使用 useEffect 挂钩将事件附加到 window 并播放音频。
  • 不建议使用数组的索引作为key prop。您应该使用 DrumPadnamekeyId,因为它已经是唯一的。在Keyboard组件的render函数中。
  • 根据上一点,您可以使用keyname来生成音频的id。这意味着不需要传递 indexNr 道具。或者您可以使用 useRef 挂钩访问 audio