Поэтому, когда я начал изучать, как использовать 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 год и 🕸️ Изучите веб-разработку с полным стеком .