Государственное свойство обновляется, а браузер - нет - PullRequest
2 голосов
/ 16 марта 2020

У меня есть 2 массива объектов, которые содержат разные звуки sr c urls. И у меня есть 2 div Q и W. Оба div связаны с первым массивом объектов, я хочу, чтобы они ассоциировались со вторым массивом каждый раз, когда другой div «Toggle PadBank» включен, так что при нажатии на него издаются разные звуки.

Каждый раз, когда вызывается 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'))

1 Ответ

1 голос
/ 16 марта 2020

Это действительно очень странно. На данный момент код действительно грязный, и я не могу точно определить, что именно с ним не так. Тем не менее, для вашего случая есть обходной путь.

Поэтому вместо того, чтобы всегда иметь аудио-тег, вы можете создать один всякий раз, когда вы нажимаете на div. Итак, что-то вроде этого

playSound(i){
    let doc = document.createElement('audio')
    doc.src = this.state.buttonState[i].url

    doc.play()
}

Вместо передачи идентификатора в вашем playSound вам нужно будет передать индекс вашего соответствующего элемента.

Это будет работать. Но, к сожалению, я не могу сказать вам, почему ваш код не работает. Я твердо думаю, что это из-за ссылок на объекты, которые вы поместили в свой код. Но на данный момент код просто слишком грязный, чтобы определить, что с ним не так за ограниченный промежуток времени.

Вот несколько вещей, которые вы можете сделать, чтобы улучшить свой код:

  1. Обновление состояний неизменно. Будьте особенно осторожны при использовании списка объектов. Создание мелкой копии не гарантирует неизменности.
  2. Повторно используйте ваши функции. Например, ваши onClick и onKeyPress имеют избыточный код.
  3. Не сравнивайте объекты напрямую. как this.state.buttonState==bankOne это может вызвать проблемы. Вместо этого сравнивайте объекты на основе уникальных ключей.

Надеюсь, это помогло. Дайте мне знать, есть ли другие проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...