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。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 罗大佑1982《之乎者也》无法盗版的青春套装版 [WAV+CUE][1G]
- 曾庆瑜1989-款款柔情[日本东芝版][WAV+CUE]
- Scelsi-IntegraledesquatuorsacordesetTrioacordes-QuatuorMolinari(2024)[24bit-WAV]
- 房东的猫2017-房东的猫[科文音像][WAV+CUE]
- 杨乃文.2016-离心力(引进版)【亚神音乐】【WAV+CUE】
- 群星.2024-珠帘玉幕影视原声带【TME】【FLAC分轨】
- 芝麻龙眼.2008-光阴隧道民歌记录3CD【乡城】【WAV+CUE】
- 谭艳《再度重相逢HQII》头版限量[低速原抓WAV+CUE][549M]
- ABC唱片《蔡琴三十周年纪念版》6N纯银镀膜 [WAV+CUE][1.1G]
- 海来阿木《西楼情歌》开盘母带[WAV+CUE][1.1G]
- TheGesualdoSix-QueenofHeartsLamentsandSongsofRegretforQueensTerrestrialandCele
- 王建杰2011-荣华富贵[喜玛拉雅][WAV+CUE]
- 孙悦2024-时光音乐会[金蜂][WAV+CUE]
- 秦宇子.2020-#YUZI【海蝶】【FLAC分轨】
- 苏有朋.1994-这般发生【华纳】【WAV+CUE】