问题描述
常见的网站布局,顶部一个导航栏,我们假设本页面共有四个栏目:分别为A、B、C、D,我们点击A,锚点跳转至A栏目,同时顶部的A按钮高亮;点击B,锚点跳转至B栏目,同时顶部的B按钮高亮;我们在Main组件里面滚动,滚动到B模块时,B按钮高亮。以上是我们经常会在开发中遇到的一个模型。如果是在以前,用jQuery作前端开发的话,实在是太熟悉不过了。
解决方案
主要想谈谈在React组件化开发中的性能优化方法。
我们的页面结构是这样的
<div className={style.main} id="main" ref={(main) => { this.main = main; }} onScroll={ ((/detail/.test(this.props.location.pathname))) "htmlcode">handleScroll() { const { changeScrollFlag } = this.props.actions; // 根据滚动距离修改TitleBox的样式 const { basicinformation, holderinformation, mainpeople, changerecord } = { basicinformation: document.getElementById('basicinformation').offsetTop - 121, holderinformation: document.getElementById('holderinformation').offsetTop - 121, mainpeople: document.getElementById('mainpeople').offsetTop - 121, changerecord: document.getElementById('changerecord').offsetTop - 121, }; if (window.screen.availHeight > this.main.scrollTop) { document.getElementById('gototop').style.display = 'none'; } else { document.getElementById('gototop').style.display = 'block'; } // 得到基础信息区域、股东信息区域、主要人员区域、变更记录区域的offsetTop,我们把它用来跟main的scrollTop比较 // 比较的结果触发action,改变TitleBox组件样式 if (this.main.scrollTop < holderinformation) { // 基础信息区域 if (basicinformation === -121) { // 如果基础信息模块不存在,我们什么也不做(当然理论上基础信息模块应该是会有的) return; } changeScrollFlag(1); return; } else if (this.main.scrollTop < mainpeople) { // 股东信息区域 changeScrollFlag(2); if (holderinformation === -121) { // 如果股东信息栏目不存在,在滚动的时候我们不应该强行把TileBox的高亮按钮设置为holderinformation // 因为holdinformation并不存在,我们跳到前一个按钮,让基础信息按钮高亮 changeScrollFlag(1); return; } return; } else if (this.main.scrollTop < changerecord) { // 主要人员区域 changeScrollFlag(3); if (mainpeople === -121) { // 如果主要人员栏目不存在,在滚动的时候我们不应该强行把TileBox的高亮按钮设置为mainpeople // mainpeople并不存在,我们跳到前一个按钮,让基础信息按钮高亮 changeScrollFlag(2); if (holderinformation === -121) { // 如果主要人员栏目不存在,而且连股东信息栏目也没有,我们跳到高亮基础信息栏目 changeScrollFlag(1); return; } return; } return; } else if (this.main.scrollTop > changerecord) { // 与上面同理 // 变更记录区域 changeScrollFlag(4); if (changerecord === -121) { changeScrollFlag(3); if (mainpeople === -121) { changeScrollFlag(2); if (holderinformation === -121) { changeScrollFlag(1); return; } return; } return; } return; } }其中,
changeScrollFlag()
函数是我们的action处理函数。
我们的函数节流
throttle() { // onScroll函数节流 let previous = 0; // previous初始设置上一次调用 onScroll 函数时间点为 0。 let timeout; const wait = 250; // 250毫秒触发一次 return () => { const now = Date.now(); const remaining = wait - (now - previous); if (remaining <= 0) { if (timeout) { window.clearTimeout(timeout); } previous = now; timeout = null; this.handleScroll(); } else if (!timeout) { timeout = window.setTimeout(this.handleScroll, wait); } }; }我们的节流函数返回一个函数,设定一个时间戳,如果我们时间戳的差值较小,我们什么也不做,但我们的时间戳的差值较大,清除定时器,触发scroll函数。这样看起来似乎挺简单,对,确实是挺简单的。
那么在子组件我们还需要怎么做呢?
接收action
二级容器型组件接收action,通过二级容器型组件传递props至三级展示型组件。
我们一定要在componentWillReceiveProps接收到这个props。
记住,在componentWillReceiveProps里使用
this.props
是并不能够接收到props的变化的!!!组件生命周期函数含有一个自己的参数。componentWillReceiveProps(nextProps) { // 在compoWillReceiveProps里接收到Main组件里所触发onScroll事件的改变activebtn样式的index // 并且设置为本组件的state this.setState({ activebtn: nextProps.scrollFlag.scrollIndex, }); }我们的state控制我们高亮的按钮是第几个,它是一个数字。
更改导航条的样式
在这里,我使用了React周边的库:classnames,详情参见其api。
<span className={classnames({ [style.informationactive]: (this.state.activebtn === 1), })} onClick={() => this.handleClick(1, 'basicinformation')} >在此,我们完成了一次从顶层组件触发事件,并做到函数节流,将事件一层层传递至底层展示型组件的一个过程。
最近一些关于前端开发的感慨
- 不要在组件中反复调用一个函数,这样会造成巨大的消耗!我们可以通过三元运算符、模板字符串做到的事情,请勿写一个新的函数。
- jsx不要太过于冗余。我们尽量写成变量的形式,不然页面结构复杂,不易于我们捕捉bug。
- 减少后端请求,能存cookie则存cookie,能存localStorge则存localStorge。
- 简单的组件尽量自己写,请勿使用别人的组件,否则在需求更改、样式调整上会出现巨大困难并做一些无意义的事儿。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】