From f78bf7c6e50cfe498791fe47c4ea0e6a1783fca1 Mon Sep 17 00:00:00 2001 From: Ihsan Etwaroo Date: Thu, 11 Aug 2016 21:41:52 -0400 Subject: [PATCH 1/2] Convert syntax to use react component --- countdown_timer.jsx | 88 +++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/countdown_timer.jsx b/countdown_timer.jsx index 59b85d0..88ff56c 100644 --- a/countdown_timer.jsx +++ b/countdown_timer.jsx @@ -1,9 +1,7 @@ -var React = require('react'); +import React, { Component, PropTypes } from 'react' // Generic Countdown Timer UI component // -// https://github.com/uken/react-countdown-timer -// // props: // - initialTimeRemaining: Number // The time remaining for the countdown (in ms). @@ -17,112 +15,110 @@ var React = require('react'); // - tickCallback(timeRemaining): Function (optional) // A function to call each tick. // -// - completeCallback(): Function (optional) -// A function to call when the countdown completes. -// -var CountdownTimer = React.createClass({ - displayName: 'CountdownTimer', +export default class CountdownTimer extends Component { - propTypes: { + static propTypes = { initialTimeRemaining: React.PropTypes.number.isRequired, interval: React.PropTypes.number, formatFunc: React.PropTypes.func, tickCallback: React.PropTypes.func, completeCallback: React.PropTypes.func - }, + } - getDefaultProps: function() { + getDefaultProps() { return { interval: 1000, - formatFunc: null, - tickCallback: null, - completeCallback: null + formatFunc: undefined, + tickCallback: undefined, + completeCallback: undefined, }; - }, + } - getInitialState: function() { + getInitialState() { // Normally an anti-pattern to use this.props in getInitialState, // but these are all initializations (not an anti-pattern). return { timeRemaining: this.props.initialTimeRemaining, - timeoutId: null, - prevTime: null + timeoutId: undefined, + prevTime: undefined }; - }, + } - componentDidMount: function() { - this.tick(); - }, + componentWillReceiveProps(newProps, oldProps) { + if (this.state.timeoutId) clearTimeout(this.state.timeoutId); + this.setState({ prevTime: undefined, timeRemaining: newProps.initialTimeRemaining }); + } - componentWillReceiveProps: function(newProps) { - if (this.state.timeoutId) { clearTimeout(this.state.timeoutId); } - this.setState({prevTime: null, timeRemaining: newProps.initialTimeRemaining}); - }, + componentDidMount() { + this.tick(); + } - componentDidUpdate: function() { + componentDidUpdate(){ if ((!this.state.prevTime) && this.state.timeRemaining > 0 && this.isMounted()) { this.tick(); } - }, + } - componentWillUnmount: function() { + componentWillUnmount() { clearTimeout(this.state.timeoutId); - }, + } + + tick() { - tick: function() { var currentTime = Date.now(); - var dt = this.state.prevTime ? (currentTime - this.state.prevTime) : 0; + var dt = currentTime - this.state.prevTime || 0; var interval = this.props.interval; // correct for small variations in actual timeout time var timeRemainingInInterval = (interval - (dt % interval)); var timeout = timeRemainingInInterval; - if (timeRemainingInInterval < (interval / 2.0)) { + if (timeRemainingInInterval < (interval / 2.0)){ timeout += interval; } var timeRemaining = Math.max(this.state.timeRemaining - dt, 0); var countdownComplete = (this.state.prevTime && timeRemaining <= 0); - if (this.isMounted()) { - if (this.state.timeoutId) { clearTimeout(this.state.timeoutId); } + if (this.isMounted()){ + if (this.state.timeoutId) clearTimeout(this.state.timeoutId); this.setState({ - timeoutId: countdownComplete ? null : setTimeout(this.tick, timeout), + timeoutId: countdownComplete ? undefined: setTimeout(this.tick, timeout), prevTime: currentTime, timeRemaining: timeRemaining }); } if (countdownComplete) { - if (this.props.completeCallback) { this.props.completeCallback(); } + if (this.props.completeCallback) { this.props.completeCallback() }; return; } if (this.props.tickCallback) { this.props.tickCallback(timeRemaining); } - }, + } + - getFormattedTime: function(milliseconds) { + getFormattedTime(milliseconds) { if (this.props.formatFunc) { return this.props.formatFunc(milliseconds); } var totalSeconds = Math.round(milliseconds / 1000); - var seconds = parseInt(totalSeconds % 60, 10); - var minutes = parseInt(totalSeconds / 60, 10) % 60; - var hours = parseInt(totalSeconds / 3600, 10); + var seconds = parseInt(totalSeconds % 60); + var minutes = parseInt(totalSeconds / 60) % 60; + var hours = parseInt(totalSeconds / 3600); seconds = seconds < 10 ? '0' + seconds : seconds; minutes = minutes < 10 ? '0' + minutes : minutes; hours = hours < 10 ? '0' + hours : hours; return hours + ':' + minutes + ':' + seconds; - }, + } - render: function() { + render() { var timeRemaining = this.state.timeRemaining; return ( @@ -131,6 +127,4 @@ var CountdownTimer = React.createClass({ ); } -}); - -module.exports = CountdownTimer; +} From 1c5876d3780dbea462ad70ade5b2867f67a8e89b Mon Sep 17 00:00:00 2001 From: Ihsan Etwaroo Date: Fri, 12 Aug 2016 22:53:23 -0400 Subject: [PATCH 2/2] Updated --- countdown_timer.jsx | 97 +++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 52 deletions(-) diff --git a/countdown_timer.jsx b/countdown_timer.jsx index 88ff56c..1df4832 100644 --- a/countdown_timer.jsx +++ b/countdown_timer.jsx @@ -25,38 +25,32 @@ export default class CountdownTimer extends Component { completeCallback: React.PropTypes.func } - getDefaultProps() { - return { - interval: 1000, - formatFunc: undefined, - tickCallback: undefined, - completeCallback: undefined, - }; + defaultProps = { + interval: 1000, + formatFunc: null, + tickCallback: null, + completeCallback: null, } - getInitialState() { - // Normally an anti-pattern to use this.props in getInitialState, - // but these are all initializations (not an anti-pattern). - return { - timeRemaining: this.props.initialTimeRemaining, - timeoutId: undefined, - prevTime: undefined - }; + state = { + timeRemaining: this.props.initialTimeRemaining, + timeoutId: null, + prevTime: null } - componentWillReceiveProps(newProps, oldProps) { - if (this.state.timeoutId) clearTimeout(this.state.timeoutId); - this.setState({ prevTime: undefined, timeRemaining: newProps.initialTimeRemaining }); + componentWillMount() { + this.isComponentMounted = false; } - componentDidMount() { - this.tick(); + isMounted() { + return this.isComponentMounted; } - componentDidUpdate(){ - if ((!this.state.prevTime) && this.state.timeRemaining > 0 && this.isMounted()) { - this.tick(); - } + componentDidMount() { + this.isComponentMounted = true; + this.tick = this.tick.bind(this) + this.getFormattedTime = this.getFormattedTime.bind(this) + this.tick(); } componentWillUnmount() { @@ -64,67 +58,66 @@ export default class CountdownTimer extends Component { } tick() { - var currentTime = Date.now(); - var dt = currentTime - this.state.prevTime || 0; + var dt = this.state.prevTime ? (currentTime - this.state.prevTime) : 0; var interval = this.props.interval; // correct for small variations in actual timeout time var timeRemainingInInterval = (interval - (dt % interval)); var timeout = timeRemainingInInterval; - if (timeRemainingInInterval < (interval / 2.0)){ + if (timeRemainingInInterval < (interval / 2.0)) { timeout += interval; } var timeRemaining = Math.max(this.state.timeRemaining - dt, 0); var countdownComplete = (this.state.prevTime && timeRemaining <= 0); - if (this.isMounted()){ - if (this.state.timeoutId) clearTimeout(this.state.timeoutId); + if (this.isMounted()) { + if (this.state.timeoutId) { clearTimeout(this.state.timeoutId); } this.setState({ - timeoutId: countdownComplete ? undefined: setTimeout(this.tick, timeout), + timeoutId: countdownComplete ? null : setTimeout(this.tick, timeout), prevTime: currentTime, timeRemaining: timeRemaining }); } if (countdownComplete) { - if (this.props.completeCallback) { this.props.completeCallback() }; + if (this.props.completeCallback) { this.props.completeCallback(); } return; } if (this.props.tickCallback) { this.props.tickCallback(timeRemaining); } - } +} - getFormattedTime(milliseconds) { - if (this.props.formatFunc) { - return this.props.formatFunc(milliseconds); - } +getFormattedTime = (milliseconds) => { + if (this.props.formatFunc) { + return this.props.formatFunc(milliseconds); + } - var totalSeconds = Math.round(milliseconds / 1000); + var totalSeconds = Math.round(milliseconds / 1000); - var seconds = parseInt(totalSeconds % 60); - var minutes = parseInt(totalSeconds / 60) % 60; - var hours = parseInt(totalSeconds / 3600); + var seconds = parseInt(totalSeconds % 60); + var minutes = parseInt(totalSeconds / 60) % 60; + var hours = parseInt(totalSeconds / 3600); - seconds = seconds < 10 ? '0' + seconds : seconds; - minutes = minutes < 10 ? '0' + minutes : minutes; - hours = hours < 10 ? '0' + hours : hours; + seconds = seconds < 10 ? '0' + seconds : seconds; + minutes = minutes < 10 ? '0' + minutes : minutes; + hours = hours < 10 ? '0' + hours : hours; - return hours + ':' + minutes + ':' + seconds; - } + return hours + ':' + minutes + ':' + seconds; +} - render() { - var timeRemaining = this.state.timeRemaining; +render() { + var timeRemaining = this.state.timeRemaining; - return ( -
- {this.getFormattedTime(timeRemaining)} -
+ return ( +
+ {this.getFormattedTime(timeRemaining)} +
); - } +} }