Не работает функция в React-приложении

Рейтинг: 0Ответов: 1Опубликовано: 25.08.2023

Есть код:

import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
import React from 'https://esm.sh/react@18.2.0';

class App extends React.Component{
  constructor(props){
    super(props);
    
    this.state = {
      timeLeftM: 0,
      timeLeftS: 0,
      breakLeght: 5,
      sesionLeght: 25,
      onTimer: false,
      
      onSession: true,
    }
    
    this.handleSessionAdd = this.handleSessionAdd.bind(this);
    this.handleBreakAdd = this.handleBreakAdd.bind(this);
    
    this.handleSessionInc = this.handleSessionInc.bind(this);
    this.handleBreakInc = this.handleBreakInc.bind(this);
    
    this.handleReset = this.handleReset.bind(this);
    this.handleTimer = this.handleTimer.bind(this);
    this.countDown = this.countDown.bind(this);
    this.resetTimer = this.resetTimer.bind(this);
  }
  
  handleTimer(event){
    if(!this.state.onTimer){
      if(this.state.timeLeftM === 0){
        this.setState(
          {
            timeLeftM: this.state.sesionLeght,
          }
        )
      }
      this.state.timerId = window.setInterval(()=>this.countDown(), 1000);
    } else {
      this.resetTimer();
    }
    
    this.setState(
        {
          onTimer: !this.state.onTimer,
        }
      )
  }
  
  resetTimer(event){
    window.clearTimeout(this.state.timerId);
  }
  
  countDown(event){
    if((this.state.timeLeftS === 0) && (this.state.timeLeftM === 0)){
      if(this.state.onSession){
        this.setState(
          {
            onSession: false,
            timeLeftM: this.state.breakLeght,
          }
        )
      } else {
        this.setState(
          {
            onSession: true,
            timeLeftM: this.state.sesionLeght,
          }
        )
      }
      
      this.audioPlay(false);
    }
    
    if(this.state.onTimer){
      if(this.state.timeLeftS == 0){
        this.setState(
          {
            timeLeftS: 59,
            timeLeftM: this.state.timeLeftM - 1,
          }
        )
    } else {
      this.setState(
          {
            timeLeftS: this.state.timeLeftS - 1,
          }
        )
      }
    } else {
      this.resetTimer();
    }
  }
  
  handleSessionAdd(event){
    if(this.state.sesionLeght < 60){
        console.log(this.state.timeLeftM);
        this.setState(
          {
            sesionLeght: this.state.sesionLeght + 1,
          }
        )
      }
  }
  
  handleBreakAdd(event){
    if(this.state.breakLeght < 60){ 
        console.log(this.state.breakLeght)
        this.setState(
          {
            breakLeght: this.state.breakLeght + 1,
          }
        )
      }
  }
  
  handleSessionInc(event){
    if(this.state.sesionLeght >= 2){
        this.setState(
          {
            sesionLeght: this.state.sesionLeght - 1,
          }
        )
      }
  }
  
  handleBreakInc(event){
    this.setState(
          {
            breakLeght: this.state.breakLeght - 1,
          }
        )
  }
  
  audioPlay(onPlay){
    this.audioRes = document.getElementById('beep');
    this.audioRes.play();
    
    if(onPlay){
      this.audioRes.pause();
      this.audioId.currentTime = 0;
    }
  }
  
  handleReset(event){
    this.resetTimer();
    this.audioPlay(true);
    this.setState(
      {
        timeLeftM: 0,
        timeLeftS: 0,
        breakLeght: 5,
        sesionLeght: 25,
        onTimer: false,

        onSession: true,
      }
    )
  }
  
  render(){
    return(
      <>
        <div id = '25c5'><h3>25 + 5 Clock</h3></div>
        
        <div className = 'row row-cols-2 g-2'>
          <div className = 'col-2'>
            <div id="break-label">Break Length</div><br/>
            <button id="break-decrement" className = 'col btn btn-warning btn-sm' onClick = {this.handleBreak} onClick = {this.handleBreakAdd}>Break Decrement</button><br/>
            <div className = 'col'><p></p></div>
            <div id="break-length" className = 'col'><h2>{this.state.breakLeght}</h2></div>
            <button id="break-increment" className = 'col btn btn-warning btn-sm' onClick = {this.handleBreakInc}>Break Increment</button>
          </div>
          
          <div className = 'col-2'>
            <div id="session-label">Session Lenght</div><br/>
            <button id="session-decrement" className = 'col btn btn-warning btn-sm' onClick = {this.handleSessionAdd}>Session Decrement</button>
            <div className = 'col'><p></p></div>
            <div id="session-length" className = 'col'><h2>{this.state.sesionLeght}</h2></div>
            <button id="session-increment" className = 'col btn btn-warning btn-sm' onClick = {this.handleSessionInc}>Session Increment</button>
          </div>
        </div>
        
        <br />
        <div id="timer-label"><h3>{ this.state.onSession ? 'Session' : 'Break' }</h3></div>
        <div id="time-left">{this.state.timeLeftM < 10 ? '0' + this.state.timeLeftM : this.state.timeLeftM}:{this.state.timeLeftS < 10 ? '0' + this.state.timeLeftS : this.state.timeLeftS}</div>
        
        <button className = 'btn btn-warning' id="start_stop" onClick = {this.handleTimer}>Start/Stop</button><br /><br />
        <button className = 'btn btn-warning' id="reset" onClick = {this.handleReset}>Reset</button>
        
        <audio id = "beep" preload = "auto" src = "https://raw.githubusercontent.com/freeCodeCamp/cdn/master/build/testable-projects-fcc/audio/BeepSound.wav" />
      </>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
#root{
  left: 55px;
  position: relative;
  widht: calc(100% - 110px);
  justify-content: center;
}
<script src="https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js"></script>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      content="Project : Build a 25 + 5 Clock for freecodecamp"
    />
    
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Teko:wght@700&display=swap" rel="stylesheet">

    <title>A 25 + 5 Clock</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id='container'></div>
    
  </body>
</html>

В чём смысл. Часы, при нажатии на кнопку reset должны вернутся к стандартному state. Раньше работало, но почему-то перестало (не работает handleReset)

Ответы

▲ 0Принят

Часы, при нажатии на кнопку reset должны вернутся к стандартному state. Раньше работало, но почему-то перестало (не работает handleReset)

Я нашел у тебя странное присваивание this.audioId.currentTime = 0... В твоем примере оно портило все дело. Закомментировал - работает

class App extends React.Component {
  constructor(props){
    super(props);
    
    this.state = {
      timeLeftM: 0,
      timeLeftS: 0,
      breakLeght: 5,
      sesionLeght: 25,
      onTimer: false,
      
      onSession: true,
    }
    
    this.handleSessionAdd = this.handleSessionAdd.bind(this);
    this.handleBreakAdd = this.handleBreakAdd.bind(this);
    
    this.handleSessionInc = this.handleSessionInc.bind(this);
    this.handleBreakInc = this.handleBreakInc.bind(this);
    
    this.handleReset = this.handleReset.bind(this);
    this.handleTimer = this.handleTimer.bind(this);
    this.countDown = this.countDown.bind(this);
    this.resetTimer = this.resetTimer.bind(this);
  }
  
  handleTimer(event){
    if(!this.state.onTimer){
      if(this.state.timeLeftM === 0){
        this.setState(
          {
            timeLeftM: this.state.sesionLeght,
          }
        )
      }
      this.state.timerId = window.setInterval(()=>this.countDown(), 1000);
    } else {
      this.resetTimer();
    }
    
    this.setState(
        {
          onTimer: !this.state.onTimer,
        }
      )
  }
  
  resetTimer(event){
    window.clearTimeout(this.state.timerId);
  }
  
  countDown(event){
    if((this.state.timeLeftS === 0) && (this.state.timeLeftM === 0)){
      if(this.state.onSession){
        this.setState(
          {
            onSession: false,
            timeLeftM: this.state.breakLeght,
          }
        )
      } else {
        this.setState(
          {
            onSession: true,
            timeLeftM: this.state.sesionLeght,
          }
        )
      }
      
      this.audioPlay(false);
    }
    
    if(this.state.onTimer){
      if(this.state.timeLeftS == 0){
        this.setState(
          {
            timeLeftS: 59,
            timeLeftM: this.state.timeLeftM - 1,
          }
        )
    } else {
      this.setState(
          {
            timeLeftS: this.state.timeLeftS - 1,
          }
        )
      }
    } else {
      this.resetTimer();
    }
  }
  
  handleSessionAdd(event){
    if(this.state.sesionLeght < 60){
        console.log(this.state.timeLeftM);
        this.setState(
          {
            sesionLeght: this.state.sesionLeght + 1,
          }
        )
      }
  }
  
  handleBreakAdd(event){
    if(this.state.breakLeght < 60){ 
        console.log(this.state.breakLeght)
        this.setState(
          {
            breakLeght: this.state.breakLeght + 1,
          }
        )
      }
  }
  
  handleSessionInc(event){
    if(this.state.sesionLeght >= 2){
        this.setState(
          {
            sesionLeght: this.state.sesionLeght - 1,
          }
        )
      }
  }
  
  handleBreakInc(event){
    this.setState(
          {
            breakLeght: this.state.breakLeght - 1,
          }
        )
  }
  
  audioPlay(onPlay){
    this.audioRes = document.getElementById('beep');
    this.audioRes.play();
    
    if(onPlay){
      this.audioRes.pause();
      /* тут закомментировал */
      //this.audioId.currentTime = 0;
    }
  }
  
  handleReset(event){
    this.resetTimer();
    this.audioPlay(true);
    this.setState(
      {
        timeLeftM: 0,
        timeLeftS: 0,
        breakLeght: 5,
        sesionLeght: 25,
        onTimer: false,

        onSession: true,
      }
    )
  }
  
  render(){
    return(
      <section>
        <div id = '25c5'><h3>25 + 5 Clock</h3></div>
        
        <div className = 'row row-cols-2 g-2'>
          <div className = 'col-2'>
            <div id="break-label">Break Length</div><br/>
            <button id="break-decrement" className = 'col btn btn-warning btn-sm' onClick = {this.handleBreak} onClick = {this.handleBreakAdd}>Break Decrement</button><br/>
            <div className = 'col'><p></p></div>
            <div id="break-length" className = 'col'><h2>{this.state.breakLeght}</h2></div>
            <button id="break-increment" className = 'col btn btn-warning btn-sm' onClick = {this.handleBreakInc}>Break Increment</button>
          </div>
          
          <div className = 'col-2'>
            <div id="session-label">Session Lenght</div><br/>
            <button id="session-decrement" className = 'col btn btn-warning btn-sm' onClick = {this.handleSessionAdd}>Session Decrement</button>
            <div className = 'col'><p></p></div>
            <div id="session-length" className = 'col'><h2>{this.state.sesionLeght}</h2></div>
            <button id="session-increment" className = 'col btn btn-warning btn-sm' onClick = {this.handleSessionInc}>Session Increment</button>
          </div>
        </div>
        
        <br />
        <div id="timer-label"><h3>{ this.state.onSession ? 'Session' : 'Break' }</h3></div>
        <div id="time-left">{this.state.timeLeftM < 10 ? '0' + this.state.timeLeftM : this.state.timeLeftM}:{this.state.timeLeftS < 10 ? '0' + this.state.timeLeftS : this.state.timeLeftS}</div>
        
        <button className = 'btn btn-warning' id="start_stop" onClick = {this.handleTimer}>Start/Stop</button><br /><br />
        <button className = 'btn btn-warning' id="reset" onClick = {this.handleReset}>Reset</button>
        
        <audio id = "beep" preload = "auto" src = "https://raw.githubusercontent.com/freeCodeCamp/cdn/master/build/testable-projects-fcc/audio/BeepSound.wav" />
      </section>
    )
  }
}

const domContainer = document.querySelector('#container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
#root{
  left: 55px;
  position: relative;
  widht: calc(100% - 110px);
  justify-content: center;
}
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      content="Project : Build a 25 + 5 Clock for freecodecamp"
    />
    
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Teko:wght@700&display=swap" rel="stylesheet">

<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

    <title>A 25 + 5 Clock</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id='container'></div>
    
  </body>
</html>