2020-09-16

React倒计时功能实现——解耦通用

React中一个倒计时功能,从实现,到改进,再到解耦抽离成公共模块。

React倒计时功能实现——解耦通用

需求分析

需求

在某个页面中需要有一个倒计时的功能,倒计时 5 s,5s钟后跳转到新的界面

分析

  • 首先是实现倒计时功能
  • 其次是实现在每倒计时 1 s后页面上要执行 倒计时秒数变化的功能
  • 最后是实现倒计时完成后 跳转到指定页面的功能

初版做法

代码

let waitTime = 5class DemoPage extends React.Component {	constructor(props) {		super(props);		this.state = {			time: '',		};	}	componentDidMount = () => {		this.countDown(); };	countDown = () => {  if (waitTime > 0) {   waitTime--;   this.setState({    time:waitTime   })  } else {   history.push('/Login')   return;  }  setTimeout(() => {   this.countDown();  }, 1000);	}	render() {		todoInfo = this.state.time + '秒后跳转至登录界面';		return (			<div>				todoInfo			</div>		);	}}export default DemoPage;

问题分析

时间设置为全局变量,糟糕的做法,

  • 修改不方便
  • 难于阅读和理解
  • 全局变量的值极不安全,可能被任何程序修改

改进版

代码

class DemoPage extends React.Component {	constructor(props) {		super(props);		this.state = {			time: '',		};	}	componentDidMount = () => {		this.countDown(5);//倒计时时间可随意调整,且可读性强 };	countDown = (waitTime) => {  if (waitTime > 0) {   waitTime--;   this.setState({    time:waitTime   })  } else {   history.push('/Login')   return;  }  setTimeout(() => {   this.countDown(waitTime);  }, 1000);	}	render() {		todoInfo = this.state.time + '秒后跳转至登录界面';		return (			<div>				todoInfo			</div>		);	}}export default DemoPage;

改进后将时间作为参数放到countDown里面,方便随意设置倒计时时间

进一步分析问题:

上面的做法,

  • setState的操作只能写在本组件,与本组件紧耦合在一起,无法实现多组件复用
  • history.push('/Login') 只能用在umi 框架中,与框架紧耦合在一起,无法实现普适应用

进一步改进

针对本问题的需求,可以将业务场景扩大为:

  • 倒计时功能
  • 倒计时过程中 需要做某事 doSomethingDuringCountDown()
  • 倒计时结束后 需要做某事 doSomethingAfterCountDown()

这样的话,倒计时的功能就可以使用的更加的灵活了。

方案

将函数作为参数传递到countDown()方法中

doSomethingDuringCountDown()doSomethingAfterCountDown()作为参数传递到countDown方法中,

具体的方法实现,根据自己页面的需求来实现。

代码

//utils.jsexport countDown = (waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown){  if (waitTime > 0) {  waitTime--;   if(doSomethingDuringCountDown){    doSomethingDuringCountDown()   }   } else {   if(doSomethingAfterCountDown){    doSomethingAfterCountDown()   }    return;  }  setTimeout(() => {   countDown(waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown);  }, 1000);}

实例

//DemoPage.jsximport { countDown } from 'utils.js'class DemoPage extends React.Component {	constructor(props) {		super(props);		this.state = {			time: '',		};	}	componentDidMount = () => {		countDown(5,this.waitTimeStateChange,this.linkTo); } waitTimeStateChange = (time) => {  this.setState({   time: time,  }) } linkTo = () => {  history.push(ToBeReviewedShowData.linkUrl) }		render() {		todoInfo = this.state.time + '秒后跳转至登录界面'		return (			<div>				todoInfo			</div>		)	}}export default DemoPage
React倒计时功能实现——解耦通用
跨境电商真人秀《我是传奇》预告片手机trademanagerskyeeWish主图及附图设计技巧!aeo跨境电商独立站or电商平台,电商出海需注意四点!跨境寒冬下2019年该如何打造一支优秀的电商团队Deutsche Post World Netetoro聚贸敦煌网2019年4月1日最后期限!美亚超过200笔订单即需交税!亚马逊将于周四公布财报 以下几点值得关注别踩雷!Facebook 广告投放新规定已施行Google 自建站SEO技术初级课程第一期:Google 最新算法Rankbrain解析课件及视频2019年1月1日电商法正式实施!这些要点跨境电商企业要重点注意啦!

No comments:

Post a Comment