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


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

    需求分析

    需求

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

    分析

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

    初版做法

    代码

    let waitTime = 5
    class 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.js
    
    export countDown = (waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown){
          if (waitTime > 0) {
            waitTime--;
              if(doSomethingDuringCountDown){
                   doSomethingDuringCountDown()
              }    
            } else {
                if(doSomethingAfterCountDown){
                    doSomethingAfterCountDown()
                }  
                return;
            }
            setTimeout(() => {
                countDown(waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown);
            }, 1000);
    }
    

    实例

    //DemoPage.jsx
    import { 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
    
  • 相关阅读:
    JDBC 删除数据两种方式,PreparedStatement表示预编译的 SQL 语句的对象,防止sql注入
    MySQL 主键外键
    JDBC 增删改查
    MySQL数据库语句
    反射
    如何安装、配置、登陆MySQL
    如何干净卸除MySQL数据库
    IO流总结
    字符流五种读写 字符流 BufferedWriter BufferedReader 带缓冲区的字符流
    单例模式
  • 原文地址:https://www.cnblogs.com/CherishTheYouth/p/CherishTheYouth_20200916.html
Copyright © 2020-2023  润新知