国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

使用react render props實現倒計時的示例代碼

2019-11-19 12:23:21
字體:
來源:轉載
供稿:網友

react的組件模式可以觀看Michael Chan的演講視頻,平時大家常聽到的react模式也是HOC, HOC的使用場景很多,譬如react-redux的connect,這里不贅述HOC相關,感興趣可以自行了解。

首先是這樣一個場景,我的業務需要實現倒計時,倒計時你懂得,倒計時經常應用在預告一個活動的開始,像秒殺,像開售搶購等,或者活動的截止。

我們來梳理一下這個倒計時的功能:

  • 定時更新時間,以秒為度;
  • 可以更新倒計時的截止時間,比如從10月1日更新為10月2日;
  • 倒計時結束,執行對應結束邏輯;
  • 倒計時結束,開啟另一個活動倒計時;
  • 同時有多個倒計時;

這個時候我便開始編碼,考慮代碼復用,我用Class的模式實現一個倒計時:

class Timer { constructor(time, countCb, timeoutCb) {  this.countCb = countCb;  this.timeoutCb = timeoutCb;  this.setDelayTime(time); } intervalId = null; clearInterval = () => {  if (this.intervalId) {   clearInterval(this.intervalId);  } } // 更新倒計時的截止時間 setDelayTime = (time) => {  this.clearInterval();  if (time) {   this.delayTime = time;   this.intervalId = setInterval(() => {    this.doCount();   }, 1000);  } } doCount = () => {  const timeDiffSecond =   `${this.delayTime - Date.now()}`.replace(//d{3}$/, '000') / 1000;  if (timeDiffSecond <= 0) {   this.clearInterval();   if (typeof this.timeoutCb === 'function') {    this.timeoutCb();   }   return;  }  const day = Math.floor(timeDiffSecond / 86400);  const hour = Math.floor((timeDiffSecond % 86400) / 3600);  const minute = Math.floor((timeDiffSecond % 3600) / 60);  const second = Math.floor((timeDiffSecond % 3600) % 60);  // 執行回調,由調用方決定顯示格式  if (typeof this.countCb === 'function') {   this.countCb({    day,    hour,    minute,    second,   });  } }}export default Timer;

通過class的方式可以實現我的上述功能,將格式顯示交給調用方決定,Timer只實現倒計時功能,這并沒有什么問題,我們看調用方如何使用:

 // 這是一個react組件部分代碼  componentDidMount() {  // 開啟倒計時  this.countDownLiveDelay(); } componentDidUpdate() {  // 開啟倒計時  this.countDownLiveDelay(); } componentWillUnmount() {  if (this.timer) {   this.timer.clearInterval();  } } timer = null; countDownLiveDelay = () => {  const {   countDownTime,   onTimeout,  } = this.props;  if (this.timer) { return; }  const time = countDownTime * 1000;  if (time <= Date.now()) {   onTimeout();  }  // new 一個timer對象  this.timer = new Timer(time, ({ hour, minute, second }) => {   this.setState({    timeDelayText: `${formateTimeStr(hour)}:${formateTimeStr(minute)}:${formateTimeStr(second)}`,   });  }, () => {   this.timer = null;   if (typeof onTimeout === 'function') {    onTimeout();   }  }); } render() {  return (   <span style={styles.text}>{this.state.timeDelayText}</span>  ); }

查看這種方式的調用的缺點:調用方都需要手動開啟倒計時,countDownLiveDelay方法調用

總感覺不夠優雅,直到我看到了react的render props, 突然靈關一現,來了下面這段代碼:

let delayTime;// 倒計時組件class TimeCountDown extends Component { state = {  day: 0,  hour: 0,  minute: 0,  second: 0, } componentDidMount() {  delayTime = this.props.time;  this.startCountDown(); } componentDidUpdate() {  if (this.props.time !== delayTime) {   delayTime = this.props.time;   this.clearTimer();   this.startCountDown();  } } timer = null; clearTimer() {  if (this.timer) {   clearInterval(this.timer);   this.timer = null;  } } // 開啟計時 startCountDown() {  if (delayTime && !this.timer) {   this.timer = setInterval(() => {    this.doCount();   }, 1000);  } } doCount() {  const {   onTimeout,  } = this.props;  // 使用Math.floor((delayTime - Date.now()) / 1000)的話會導致這里值為0,前面delayTime - Date.now() > 0  const timeDiffSecond = (delayTime - `${Date.now()}`.replace(//d{3}$/, '000')) / 1000;  if (timeDiffSecond <= 0) {   this.clearTimer();   if (typeof onTimeout === 'function') {    onTimeout();   }   return;  }  const day = Math.floor(timeDiffSecond / 86400);  const hour = Math.floor((timeDiffSecond % 86400) / 3600);  const minute = Math.floor((timeDiffSecond % 3600) / 60);  const second = Math.floor((timeDiffSecond % 3600) % 60);  this.setState({   day,   hour,   minute,   second,  }); } render() {  const {   render,  } = this.props;  return render({   ...this.state,  }); }}export default TimeCountDown;

具體TimeCountDown代碼可戳這里

調用方:

import TimeCountDown from 'TimeCountDown';function formateTimeStr(num) { return num < 10 ? `0${num}` : num;}// 業務調用倒計時組件class CallTimer extends Component { onTimeout = () => {  this.forceUpdate(); } render() {  // 傳遞render函數  return (   <span style={styles.statusText}>    距直播還有    <TimeCountDown      time={time}      onTimeout={() => { this.onTimeout(); }}      render={({ hour, minute, second }) => {       return (        <span>         {formateTimeStr(hour)}:{formateTimeStr(minute)}:{formateTimeStr(second)}        </span>       );      }}     />      </span>  ) }}

對比這種方式,通過傳遞一個函數render方法給到TimeCountDown組件,TimeCountDown組件渲染時執行props的render方法,并傳遞TimeCountDown的state進行渲染,這就是render props的模式了,這種方式靈活、優雅很多,很多場景都可以使用這種方式,而無需使用HOC。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南康市| 株洲市| 佛坪县| 闻喜县| 南乐县| 郁南县| 霍城县| 崇州市| 新乐市| 大连市| 桂林市| 和田市| 香河县| 扎赉特旗| 四会市| 天柱县| 沈丘县| 廉江市| 永靖县| 安平县| 年辖:市辖区| 永济市| 峨眉山市| 光泽县| 云南省| 朝阳县| 盱眙县| 娄底市| 托克托县| 金沙县| 陆良县| 澄迈县| 图片| 辽源市| 淮北市| 丽江市| 苍南县| 南平市| 银川市| 邹平县| 大埔县|