我有2个对象数组,其中包含不同的声音src url。我有2个div Q和W。两个div都与第一个对象数组相关联,我想在每次另一个div“ Toggle PadBank”时将它们与第二个数组相关联是onClicked的,因此单击它们时会产生不同的声音。
每次调用togglePadBank时,都会设置状态,以便buttonState指向第二个数组。我的控制台正在记录日志状态及其变化,但浏览器仍指向旧的对象数组。
这是我的代码笔:https://codepen.io/freeCodeCamp/pen/MJyNMd?editors=1010和 这是我的代码:
let bankOne = [{
key:"Q",
col:"blue",
audioId: '1',
url: 'https://s3.amazonaws.com/freecodecamp/drums/Chord_1.mp3'
}, {
key:"W",
col:"blue",
audioId:'2',
url: 'https://s3.amazonaws.com/freecodecamp/drums/Chord_2.mp3'
} ]
let bankTwo = [{
key:"Q",
col:'blue',
audioId:'3',
url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3'
}, {
key:"W",
col:"blue",
audioId:"4",
url: 'https://s3.amazonaws.com/freecodecamp/drums/Heater-2.mp3'
} ]
class Buttons extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<div>
<div style={{width:'100px', height:"100px", backgroundColor:this.props.color}} id={this.props.id} onClick={this.props.handleClick}><h3>{this.props.id} </h3></div>
<audio id={this.props.audioId}>
<source src={this.props.urlSource}/>
</audio>
</div>
)
}
}
class MyApp extends React.Component{
constructor(props){
super(props)
this.state={
buttonState:bankOne,
padBankCol:"blue",
currentPadBank:"bankOne"
}
this.handlesClick=this.handlesClick.bind(this)
this.handleKeyDown=this.handleKeyDown.bind(this)
this.playSound=this.playSound.bind(this)
this.togglePadBank=this.togglePadBank.bind(this)
}
handlesClick(event){
let indx=""
let clickId=event.target.id
let newState=Object.assign({},this.state)
for(let i=0;i<this.state.buttonState.length;i++){
if(this.state.buttonState[i].key===clickId){
let soundId1=this.state.buttonState[i].audioId
indx=i
newState.buttonState[i].col="red"
this.setState(
newState
)
this.playSound(soundId1)
}
}
setTimeout(()=>{
newState.buttonState[indx].col="blue"
this.setState(
newState
)
},1000)
}
handleKeyDown(event){
let indx=""
let keyPress=String.fromCharCode(event.keyCode)
console.log(keyPress)
let newState=Object.assign({},this.state)
for(let i=0;i<this.state.buttonState.length;i++){
if(this.state.buttonState[i].key===keyPress){
let soundId1=this.state.buttonState[i].audioId
indx=i
newState.buttonState[i].col="red"
this.setState(
newState
)
this.playSound(soundId1)
}
}
setTimeout(()=>{
newState.buttonState[indx].col="blue"
this.setState(
newState
)
},1000)
}
playSound(id){
let sound=document.getElementById(id)
sound.play()
}
togglePadBank(){
if(this.state.buttonState==bankOne){
this.setState({
buttonState:bankTwo,
padBankCol:"red",
currentPadBank:"bankTwo"
})
console.log(this.state.buttonState)
}
else if(this.state.buttonState==bankTwo){
this.setState({
buttonState:bankOne,
padBankCol:"blue",
currentPadBank:"bankOne"
} )
console.log(this.state.buttonState)
}
}
render(){
document.addEventListener("keydown",this.handleKeyDown)
return(
<div>
<div style={{width:'400px',height:'400px', display:'flex',flexDirection:'row',backgroundColor:'green'}}>
<Buttons id="Q" color= {this.state.buttonState[0].col} handleClick={this.handlesClick} urlSource={this.state.buttonState[0].url} audioId={this.state.buttonState[0].audioId}/>
<Buttons id="W" color={this.state.buttonState[1].col} handleClick={this.handlesClick} audioId={this.state.buttonState[1].audioId} urlSource={this.state.buttonState[1].url} />
<div style={{width:"100px",height:"50px",position:"relative",backgroundColor:this.state.padBankCol,left:"70px",top:"100px"}} onClick={this.togglePadBank}>Pad Bank Toggle</div>
</div>
</div>
)
}
}
ReactDOM.render(<MyApp />, document.getElementById('root'))
答案 0 :(得分:1)
这确实很奇怪。在这一点上,代码真的很混乱,我无法指出它到底有什么问题。但是,您的情况有一种解决方法。
因此,当您单击div时,您可以创建一个,而不是始终使用音频标签。像这样
playSound(i){
let doc = document.createElement('audio')
doc.src = this.state.buttonState[i].url
doc.play()
}
您需要传递匹配项的索引,而不是在playSound
中传递ID。
这将起作用。但是很遗憾,我无法告诉您您的代码为什么不起作用。我强烈认为这是由于引用了您在代码中放入的对象。但是到目前为止,该代码实在太脏了,无法在有限的时间间隔内找出问题所在。
您可以采取以下措施来改进代码:
this.state.buttonState==bankOne
一样会在这里引起麻烦。而是根据唯一键比较对象。我希望能有所帮助。让我知道是否还有其他麻烦。