成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于React與Redux的留言墻的實(shí)現(xiàn)

MockingBird / 375人閱讀

摘要:設(shè)計(jì)本次留言墻分為兩部分?;顒?dòng)展示部分為匿名留言墻形式后改為實(shí)名制,需要根據(jù)收到的留言墻進(jìn)行向上平滑滾動(dòng),如果沒有消息接收則停止在最后一條消息上。主要為處理數(shù)據(jù)的數(shù)據(jù)層。

背景

由于某事業(yè)群需要留言墻用于年會(huì),同時(shí)需要調(diào)用大象公眾號(hào)服務(wù)器接口,所以在今年年初開發(fā)了留言墻用于活動(dòng)現(xiàn)場(chǎng)交流。

設(shè)計(jì)

本次留言墻分為兩部分。一部分為活動(dòng)展示部分,另一部分為后臺(tái)審批部分。

活動(dòng)展示部分為匿名留言墻形式(后改為實(shí)名制),需要根據(jù)收到的留言墻進(jìn)行向上平滑滾動(dòng),如果沒有消息接收則停止在最后一條消息上。

后臺(tái)審批部分為管理人員對(duì)用戶像某個(gè)特定公眾號(hào)發(fā)送的特定格式消息進(jìn)行審核,符合上墻要求的消息則通過審核,通過活動(dòng)展示頁(yè)面進(jìn)行展示。

技術(shù)方案 React

該項(xiàng)目采用了React作為View層的渲染框架。關(guān)于React的簡(jiǎn)單介紹,大家可以戳阮一峰的博客React 入門實(shí)例教程, 需要系統(tǒng)學(xué)習(xí)的同學(xué)可以戳React的官方網(wǎng)站React英文版,React中文版。建議大家閱讀React英文版網(wǎng)站,中文版網(wǎng)站相對(duì)于英文版網(wǎng)站來(lái)說(shuō)缺少了一部分內(nèi)容,例如React的children部分,可能是由于英文文檔更新導(dǎo)致的翻譯不太及時(shí)的原因。

Redux

Redux的學(xué)習(xí)可以通過Redux中文文檔來(lái)進(jìn)行。里面有很多的示例能夠輔助進(jìn)行學(xué)習(xí)。具體使用方法會(huì)通過后面的步驟進(jìn)行介紹。

實(shí)現(xiàn) React

在View層中,有兩個(gè)組件。

Message

    
{this.props.flag === false ? : ""}
{this.props.uname} [{this.parseDate(this.props.sendTime)}] {this.props.text} {this.props.flag === true ? this.props.approve === 0 ? : "已通過" : ""}

MsgList

    
    {this.props.msgs.map((message, index) => {this.props.approveMsg(index, message.id)}}/> )}

其中Message為每條消息的組件,MsgList為整個(gè)消息列表的組件。

Redux Action

Action主要為處理數(shù)據(jù)的數(shù)據(jù)層。大部分的數(shù)據(jù)操作都放在Action中,通過dispatch(Action)的方法來(lái)通知readucer進(jìn)行數(shù)據(jù)更新,從而通過react-redux來(lái)通知組件更新。
首先,會(huì)定義一些Action常量,用于操作命名。

export const WALL_REQUEST = "WALL_REQUEST";
export const WALL_REQUEST_SUCCESS = "WALL_REQUEST_SUCCESS";
export const WALL_REQUEST_FAIL = "WALL_REQUEST_FAIL";

export const CHECK_MSGS = "CHECK_MSGS";
export const CHECK_MSGS_SUCCESS = "CHECK_MSGS_SUCCESS";
export const CHECK_MSGS_FAIL = "CHECK_MSGS_FAIL";
export const MSG_REQUEST = "MSG_REQUEST";
export const MSG_REFUSE = "MSG_REFUSE";
export const MSG_PASS = "MSG_PASS";

同時(shí),會(huì)定義一些函數(shù),用于View層中與Action部分進(jìn)行通信,從而觸發(fā)某些操作。

export function fetchMsgs(number) {
    const path = "/nh/show/msg";
    return dispatch=> {
        dispatch(requestMsgs(number));
        return window.fetch(URL + path).then(response=>response.json()).then(json=>dispatch(receiveMsgs(json.data)));
    }
}

在reducer中使用了window變量中的fetch接口用于數(shù)據(jù)獲取,有關(guān)于此接口的使用我后面會(huì)寫另一篇文章來(lái)進(jìn)行介紹,大家如果需要資料可以先戳此處,需要中文版的童鞋可以戳此處。

Reducer

在Reducer中,會(huì)對(duì)當(dāng)前state中的所有數(shù)據(jù)進(jìn)行處理,改變state中的全局?jǐn)?shù)據(jù)從而驅(qū)動(dòng)組件重新渲染。

function msgsReducer(state = [], action) {
    switch(action.type) {
        case WALL_REQUEST:
        {
            return state.slice(action.number)
        }
        case WALL_REQUEST_SUCCESS:
        {
            return [
                ...state, ...action.data
            ]
        }
        default:
        {
            return state;
        }
    }
}

在reducer中一般通過Action中聲明的操作和action所帶來(lái)的參數(shù)對(duì)state進(jìn)行操作。每次都需要返回一個(gè)新的對(duì)象或者數(shù)組,而不能再原有數(shù)據(jù)上進(jìn)行修改,從而避免數(shù)據(jù)更新后組件不更新的問題。

Server

server端返回的數(shù)據(jù)為一次性數(shù)據(jù),即數(shù)據(jù)取過后就不會(huì)再返回,因此需要在前端Reducer里面對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)。由于數(shù)據(jù)為滾動(dòng)顯示,因此需要一個(gè)隊(duì)列來(lái)進(jìn)行控制。

難點(diǎn) 滾動(dòng)問題 scrollTop+setInterval

最開始的滾動(dòng)方案選擇此方案。此方案在實(shí)現(xiàn)上也最為簡(jiǎn)單。但是,當(dāng)消息數(shù)目到達(dá)1K量級(jí)時(shí),能夠明顯的感覺到有卡頓的現(xiàn)象發(fā)生,滾動(dòng)很不流暢,因此拋棄了此方法。

transform+setInterval

由于上一個(gè)方案中scrollTop在節(jié)點(diǎn)數(shù)過多的情況下會(huì)導(dǎo)致卡頓的問題,因此在滾動(dòng)上采用了transform的方法,但是由于setInterval粒度不夠小,因此對(duì)其進(jìn)行了替換。

transform+window.requestAnimationFrame

window.requestAnimationFrame是瀏覽器接口,被調(diào)用的頻率是每秒60次,但是一般會(huì)遵循W3C標(biāo)準(zhǔn)規(guī)定的頻率。使用此接口可以保證調(diào)用頻率,同時(shí)能夠配合transform的變化數(shù)字來(lái)進(jìn)行速度控制。因此采用了此方法。

節(jié)點(diǎn)刪除功能

由于在留言墻的使用過程中,會(huì)有不斷的新的節(jié)點(diǎn)產(chǎn)生并且滾動(dòng)出視口,因此為了節(jié)省內(nèi)存,需要將滾動(dòng)出視口的節(jié)點(diǎn)刪除,從而避免整個(gè)網(wǎng)頁(yè)消耗的內(nèi)存越來(lái)越大。
由于滾動(dòng)方式確定為transform的滾動(dòng)方式,因此選擇了在請(qǐng)求調(diào)用返回?cái)?shù)據(jù)后同時(shí)觸發(fā)刪除代碼,對(duì)當(dāng)前消息節(jié)點(diǎn)進(jìn)行判斷,對(duì)已經(jīng)滾動(dòng)到視口外的數(shù)據(jù)節(jié)點(diǎn)進(jìn)行刪除,并重置transform值,從而達(dá)到刪除節(jié)點(diǎn)的目的。

componentWillReceiveProps(nextProps) {
    if(this.props.flag === false && this.props.msgs.length !== nextProps.msgs.length) {
        let number = Math.floor((-this.y) / this.msgHeight),
            element = document.getElementById("wall").getElementsByTagName("ul")[0];
        if(number > 0) {
            this.y = this.y + number * this.msgHeight;
            element.style.transform = "translateY(" + (this.y) + "px)";
            return;
        }
        window.cancelAnimationFrame(this.animationId);
        this.animationId = window.requestAnimationFrame(this.scroll.bind(this));
    }
}

通過組件接收新數(shù)據(jù)渲染時(shí)來(lái)重置transform值,完成節(jié)點(diǎn)刪除工作。

不足

如果消息并發(fā)數(shù)量較多,會(huì)導(dǎo)致消息堆積在視口下方等待向上滾動(dòng),由此可能消耗大量的內(nèi)存,后續(xù)仍然需要優(yōu)化,避免所有接受到的未展示的數(shù)據(jù)都渲染出來(lái)堆積在下方。

總結(jié)

在剛開始設(shè)計(jì)時(shí)至少考慮到了滾動(dòng)的情況,并沒有考慮到消息越來(lái)越多導(dǎo)致頁(yè)面占用內(nèi)存越來(lái)越大的問題。當(dāng)完成最初版本的消息滾動(dòng)時(shí),在自己測(cè)試的過程中因?yàn)橄?shù)量過大導(dǎo)致卡頓,所以考慮到了滾動(dòng)方面的優(yōu)化與節(jié)點(diǎn)刪除的問題。transform的效率優(yōu)于scrollTop,而window.requestAnimationFrame的性能又優(yōu)于setInterval,但是在開發(fā)時(shí)間上不是特別充足,因此選擇了性能最好的技術(shù)方案,但是舍棄了一部分優(yōu)化的方案。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78908.html

相關(guān)文章

  • 基于 react, redux 最佳實(shí)踐構(gòu)建 2048

    摘要:最佳實(shí)踐一個(gè)文件一個(gè)組件。,這是包含的是無(wú)副作用的純函數(shù)式計(jì)算狀態(tài)操作的函數(shù)。,的啟動(dòng)腳本,啟動(dòng)開發(fā)模式,項(xiàng)目打包,運(yùn)行單元測(cè)試等等。每次代碼推送到之前也會(huì)執(zhí)行所有單元測(cè)試用例,全部通過才可以繼續(xù)推送。,首次安裝依賴包之后生成的文件。 前段時(shí)間 React license 的問題鬧的沸沸揚(yáng)揚(yáng),搞得 React 社區(qū)人心惶惶,好在最終 React 團(tuán)隊(duì)聽取了社區(qū)意見把 license 換...

    Eidesen 評(píng)論0 收藏0
  • React.js 最佳實(shí)踐(2016)_鏈接修正版

    摘要:譯者按最近依舊如火如荼相信大家都躍躍欲試我們團(tuán)隊(duì)也開始在領(lǐng)域有所嘗試年應(yīng)該是逐漸走向成熟的一年讓我們一起來(lái)看看國(guó)外的開發(fā)者們都總結(jié)了哪些最佳實(shí)踐年在全世界都有很多關(guān)于新的更新和開發(fā)者大會(huì)的討論關(guān)于去年的重要事件請(qǐng)參考那么年最有趣的問題來(lái)了我 譯者按:最近React(web/native)依舊如火如荼,相信大家都躍躍欲試,我們團(tuán)隊(duì)也開始在React領(lǐng)域有所嘗試. 2016年應(yīng)該是Reac...

    syoya 評(píng)論0 收藏0
  • 前端最實(shí)用書簽(持續(xù)更新)

    摘要:前言一直混跡社區(qū)突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂所以將前端主流技術(shù)做了一個(gè)書簽整理不求最多最全但求最實(shí)用。 前言 一直混跡社區(qū),突然發(fā)現(xiàn)自己收藏了不少好文但是管理起來(lái)有點(diǎn)混亂; 所以將前端主流技術(shù)做了一個(gè)書簽整理,不求最多最全,但求最實(shí)用。 書簽源碼 書簽導(dǎo)入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 評(píng)論0 收藏0
  • 企業(yè)級(jí)React項(xiàng)目個(gè)人構(gòu)建總結(jié)

    摘要:隔壁老王今日行程不同的內(nèi)容使用這種方法就可以將我們得所有路由寫在一起了,可能有人覺得每次都要寫引入很麻煩,有沒有其他更好用的辦法,在講的時(shí)候會(huì)說(shuō)到這里就先跳過。 前言 距離上篇文章已經(jīng)好長(zhǎng)一段時(shí)間了,這兩個(gè)星期公司派駐到京東方這邊出差負(fù)責(zé)入駐項(xiàng)目團(tuán)隊(duì)的前端工作。這段時(shí)間從零搭建一下前端項(xiàng)目,這次給的時(shí)間比較充裕,思考的也比較多。以前也常有搭過前端項(xiàng)目,但是給的時(shí)間都比較緊,因此很多問題...

    simpleapples 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<