Поэтому, когда я начал изучать, как использовать React, я решил, что изначально собираюсь создать часы Pomodoro, что я и сделал. Вы можете проверить это здесь". При этом я также подумал о создании таймера обратного отсчета, который имеет сходство с часами Pomodoro. Итак, мы собираемся узнать, как создать таймер с помощью React.

Во-первых, давайте разберем таймер на разные составляющие. React использует компонентную архитектуру для описания пользовательского интерфейса приложения. Наше приложение будет состоять из этих четырех компонентов

  • Компонент таймера, который будет отвечать за рендеринг таймера.
  • Компонент TimerInput, который отображает ввод формы, где вы можете ввести количество минут.
  • Компонент StartButton, представляющий кнопку для запуска таймера.
  • Компонент приложения, который служит родительским компонентом для всех других компонентов и отвечает за рендеринг элементов в DOM.

Мы собираемся строить с пустой index.html страницы, НЕТ инструментов для сборки. Итак, приступим!

Разместите это вверху своей index.html страницы

<div id="root"></div>
<script src="https:unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https:unpkg.com/[email protected]/umd/react-dom.development.js"></script>
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Давайте создадим шаблоны всех наших компонентов, перечисленных выше.

class TimerInput extends React.Component {
render() {
  return (
   <div>
      <h3>Input your desired time</h3>
      <input type="number" required />
  </div>
     );
   }
}
class Timer extends React.Component {
   render() {
      return (
       <div>
        <h1> </h1>
       </div>
     );
   }
 }
class StartButton extends React.Component {
   render() {
     return(
      <div>
       <button>Start</button>
     </div>
      );
  }
}
class App extends React.Component {
   render() {
      return (
       <div>
        <TimerInput/>
        <Timer/>
       <StartButton/>
      </div>
     );
   }
 }

Теперь давайте добавим стили нашим компонентам. Поскольку React использует JSX, расширение синтаксиса, которое позволяет нам писать JavaScript в HTML. Мы можем добавить к нашим компонентам встроенный стиль и убедиться, что они заключены в двойные скобки {{ }}

class TimerInput extends React.Component {
render() {
  return (
   <div style={{marginLeft:100}}>
      <h3>Input your desired time</h3>
      <input type="number" required />
  </div>
     );
   }
}
class Timer extends React.Component {
   render() {
      return (
       <div>
        <h1 style={{ fontSize: 100, marginLeft:100 }}> </h1>
       </div>
     );
   }
 }
class StartButton extends React.Component {
   render() {
     return(
      <div style={{ marginLeft: 130 }}>
       <button>Start</button>
     </div>
      );
  }
}
class App extends React.Component {
   render() {
      return (
       <div>
        <TimerInput/>
        <Timer/>
       <StartButton/>
      </div>
     );
   }
 }

Теперь приступим к работе над функциональностью приложения. В нашем родительском компоненте App мы собираемся установить состояние таймера.

class App extends React.Component {
    constructor(props){
    super(props);
     this.state = {
      seconds: '00',   // responsible for the seconds 
      minutes: ''  // responsible for the minutes
}
  }
   render() {
      return (
       <div>
        <TimerInput minutes={this.state.minutes}/>
        <Timer minutes={this.state.minutes} seconds={this.state.seconds}/>
       <StartButton/>
      </div>
     );
   }
 }

Обратите внимание, что мы включили реквизиты минут и секунд в компоненты TimerInput и Timer. Объект props служит «средством передвижения» для передачи данных между компонентами. Давайте посмотрим, как это отражается в компонентах TimerInput и Timer .

class TimerInput extends React.Component {
render() {
  return (
   <div style={{marginLeft:100}}>
      <h3>Input your desired time</h3>
      <input type="number" minutes={this.props.minutes} required />
  </div>
     );
   }
}
class Timer extends React.Component {
 render() {
  return (
   <div>
    <h1 style={{ fontSize: 100, marginLeft:100}}>{this.props.minutes}:{this.props.seconds}
    </h1>
       </div>
     );
   }
 }

Теперь мы хотим убедиться, что все, что пользователь вводит в форме, обновляет состояние минут. Мы достигаем этого с помощью API setState, предоставляемого React. Этот API помогает обновлять состояние приложения, вызванное событием. Итак, мы создадим метод, который будет обрабатывать это событие, которое, как только пользователь обновит желаемые минуты в форме ввода, оно обновится автоматически.

class App extends React.Component {
    constructor(props){
    super(props);
     this.state = {
      seconds: '00',   // responsible for the seconds 
      minutes: ''  // responsible for the minutes
   }
}
// bind the method to the constructor
this.handleChange = this.handleChange.bind(this);
handleChange(event) {
   this.setState({
     minutes: event.target.value
   })
}
render() {
      return (
       <div>
        <TimerInput minutes={this.state.minutes} handleChange={this.handleChange}/>
        <Timer minutes={this.state.minutes} seconds={this.state.seconds}/>
       <StartButton/>
      </div>
     );
   }
 }
// Update the TimerInput component
class TimerInput extends React.Component {
render() {
  return (
   <div style={{marginLeft:100}}>
      <h3>Input your desired time</h3>
      <input type="number" minutes={this.props.minutes} handleChange={this.props.handleChange} required />
  </div>
     );
   }
}

Теперь давайте реализуем функцию, которая обрабатывает обратный отсчет в таймере.

class App extends React.Component {
   constructor(props) {
     super(props);
this.state = {
  seconds: '00', 
  minutes: ''
}
this.secondsRemaining; 
this.intervalHandle;
this.handleChange = this.handleChange.bind(this);
// method that triggers the countdown functionality
this.startCountDown = this.startCountDown.bind(this);
this.tick = this.tick.bind(this);
}
handleChange(event) {
  this.setState({
   minutes: event.target.value
  })
}
tick() {
var min = Math.floor(this.secondsRemaining / 60);
var sec = this.secondsRemaining - (min * 60);
this.setState({
  minutes: min,
  seconds: sec
})
if (sec < 10) {
  this.setState({
    seconds: "0" + this.state.seconds,
  })
}
if (min < 10) {
this.setState({
  value: "0" + min,
 })
}
if (min === 0 & sec === 0) {
clearInterval(this.intervalHandle);
}
this.secondsRemaining--
}
startCountDown() {
this.intervalHandle = setInterval(this.tick, 1000);
let time = this.state.minutes;
this.secondsRemaining = time * 60;
}
 }

Наконец, давайте обновим наш компонент StartButton, чтобы при нажатии он запускал startCountDown()

class StartButton extends React.Component {
  render() {
    return (
  <div style={{ marginLeft: 130 }}>
  <button onClick={this.props.startCountDown}>Start</button>
 </div>
);
  }
}

Итак, вот он, наш таймер обратного отсчета теперь работает, я создал свою версию с некоторыми дополнительными функциями, вы можете проверить это здесь.

Удачного кодирования !!!

✉️ Подпишитесь на рассылку еженедельно Email Blast 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .