diff --git a/src/components/CountDown/index.js b/src/components/CountDown/index.js index c733e56b2..16cefa22d 100644 --- a/src/components/CountDown/index.js +++ b/src/components/CountDown/index.js @@ -21,7 +21,39 @@ function fixedZero(val) { return val * 1 < 10 ? `0${val}` : val; } +function initTime(target) { + let lastTime = 0; + let targetTime = 0; + try { + if (Object.prototype.toString.call(target) === '[object Date]') { + targetTime = target.getTime(); + } else { + targetTime = new Date(target).getTime(); + } + } catch (e) { + throw new Error(`invalid target prop ${e.message}`); + } + + lastTime = targetTime - new Date().getTime(); + return { + lastTime: Math.max(lastTime, 0), + }; +} + class CountDown extends Component { + + static getDerivedStateFromProps(nextProps, prevState) { + if (nextProps.target !== prevState.target) { + const {lastTime} = initTime(nextProps.target); + return { + lastTime, + target: nextProps.target, + resetTimer: true, + }; + } + return null; + } + timer = 0; interval = 1000; @@ -29,7 +61,7 @@ class CountDown extends Component { constructor(props) { super(props); - const { lastTime } = this.initTime(props); + const {lastTime} = initTime(props.target); this.state = { lastTime, @@ -40,45 +72,20 @@ class CountDown extends Component { this.tick(); } - componentWillReceiveProps(nextProps) { - const { target } = this.props; - if (target !== nextProps.target) { - clearTimeout(this.timer); - const { lastTime } = this.initTime(nextProps); - this.setState( - { - lastTime, - }, - () => { - this.tick(); - } - ); + componentDidUpdate() { + if (!this.state.resetTimer) { + return } + clearTimeout(this.timer); + this.tick(); + // eslint-disable-next-line react/no-did-update-set-state + this.setState({resetTimer: false}); } componentWillUnmount() { clearTimeout(this.timer); } - initTime = props => { - let lastTime = 0; - let targetTime = 0; - try { - if (Object.prototype.toString.call(props.target) === '[object Date]') { - targetTime = props.target.getTime(); - } else { - targetTime = new Date(props.target).getTime(); - } - } catch (e) { - throw new Error('invalid target prop', e); - } - - lastTime = targetTime - new Date().getTime(); - return { - lastTime: lastTime < 0 ? 0 : lastTime, - }; - }; - // defaultFormat = time => ( // {moment(time).format('hh:mm:ss')} // ); @@ -101,7 +108,7 @@ class CountDown extends Component { }; tick = () => { - const { onEnd } = this.props; + const { onEnd = () => {} } = this.props; let { lastTime } = this.state; this.timer = setTimeout(() => {