摘要:基于全家桶寫作新聞一體綜合應用的實踐總結在線地址大家伙兒們,又見面了。參照但不可否認非常符合的思想,都在處理大規模數據時彰顯優勢。最好的辦法是使用部署環境。細致的拆分,解耦性更好,以為單位進行修改時,大大降低誤傷率的同時,隔離無關的信息。
?CoderPad-基于React全家桶寫作/新聞一體綜合應用的實踐總結
在線地址
GITHUB
大家伙兒們,又見面了?。 自上次Byemess Todo之后,覺得自身不足還是挺多的,期間又萌生了一些將它重構加上更多新特性的想法,之后技術磨煉一陣再來好好改造它。對于Learn by doing這種事情,一次就會上癮啊有木有??,于是乎本著繼續精進練習React技術棧,以及實踐更多相關技術的初衷,besides that,自己還想再準備一個小項目來為找工作打底氣,于是乎就有了CoderPad。
? WHY IS THIS在最開始的時候,是想做一個催稿app,又是一個集成的idea:提供分類書單,可以記錄閱讀情況,然后根據這個情況設定或者后臺計算智能推薦:何時去寫一篇相關的博客(技術博客),當然寫作也是在這個app里完成,然后自動部署至github page。 名字我都想好了,就叫催乎...(知乎er們懂的),奈何這是個大工程啊... 我就造出了這么個只有編輯,閱讀的閹割版。 另外關于寫完markdown直接部署生成靜態博客的app我推薦好基友的Page.qy => ? 無代碼建站,基于Node.js,React和Electron,很用心的app,向他學習之,他馬上又會寫出一個UI逆天美的音樂播放器了,你們可以關注他。
? WHAT IT ISMarkdown: 支持本地緩存,保存/刪除/查看/下載,追求極簡。
NewsFeed: 集成v2ex,HackerNews-Top Stories, Github-Trending
Music: 暫未施工
老朋友React全家桶: 對于這塊,值得一提的是react router v4,相對于v3的巨大改動,extremely make sense. 讓route與組件化思想更貼切,有種幻覺:定義子route更加隨心所欲了。至于為什么... 請君上手感受。
Immutable: 有一些細微的坑,主要體現在數據類型轉化上,immutable會將原生JS數據類型進行包裝,如Map,List,在對它們進行提取的時候需要注意是否已經轉化為原生JS,否則容易出錯。 我的建議就是時刻注意提取的數據是什么類型,結合PropTypes進行參數檢測,出錯時先console看看,一般很快可以解決。 對于多層對象嵌套的時候,為了保險,手動將被嵌套的對象進行指定類型轉化,比如{ list: [] } => { list:Immutable.List([]) },如果要偷懶的話可以直接使用fromJS,但是這個方法滲透性強,會將所有內嵌結構進行轉化,在本項目的后期重構里就遇到了子數組遍歷出來全是immutable object的情況,需要手動再次轉化,很是惡心。 這些缺點在redux文檔里也有表述,在具體實踐后才能有更直觀的理解。 參照: What are the issues with using Immutable.JS?.但不可否認Immutable.js非常符合react的思想,都在處理大規模數據時彰顯優勢。
Reselect:它用來替代我們手寫的state selector, 它的主要思想: state1 + state2 => state3, 緩存先決state,它們如果計算結果是相同的,就使用緩存結果不去改變最終state,同樣也是immutable思想。 在結合immutable.js的時候,也是坑啊,還是那個老問題,數據類型,state嵌套越深,越麻煩。 所以,現在明白為什么強調Redux State扁平化了吧?
Redux Saga: Oh my.. 無比親切,至于原因: 我寫過這么一篇文章:From Iterator To Async. Saga致力于解決復雜場景下的異步流程控制,用它來管理action觸發,酸爽無比。 畢竟控制異步流程這種成就在JS話題下本身就是爽的不要不要的。 本質是使用generator,對于理解CO庫的同學們,掌握saga不在話下。在操作極其頻繁的場景下(比如游戲),你會感受到他的威力。 推薦一篇文章: Async operations using redux-saga, 在本項目里我主要用它來控制news數據的拉取,采用axios.
Styled Components: 老朋友,更新了2.0版本,同樣配合styled-props,效果拔群。 至于一些宏觀上的樣式設置,的確不如直接寫CSS那么直觀。 我采用的方法是,特性按組件寫,通性和一些涉及多層級樣式都放在wrapper里。 也許多帶帶使用styled-components并不能發揮出色,配合傳統CSS寫法,應該可以相得益彰。
?Problem and Solutionref: 對于ref的感覺一直是又愛又恨,畢竟在react之前,dom操作被我們玩的飛起,而react官方的態度一直是不建議使用。 在這次的項目中,markdown editor處的textarea我便采用了Uncontrolled的形式,使用ref保存dom引用。 初衷是為了對頻繁的內容變動進行debounce處理,當編輯暫停時才觸發一次內容state更新。 隨著組件的增加,在一個嵌套達到3層的modal組件里,需要對textarea的value進行重置操作,好了,這下我得從父組件一層層的把這個ref傳進去。 那感覺簡直不能再糟.... 一剎那感覺官方文檔就像和藹的老司機,句句肺腑之言啊! 不過在你真的遇到這個坑前,是不會有多深的感受的。 要解決這個惡心的傳遞,只有采用controlled形式,onChange監聽,value直接鏈接state.
Perf: 作為性能測量的利器,測試結果讓我發現styled-components的消耗是可觀的,尤其是更新到v2.0版本后。在其他方面,由于本項目里的newsFeed可能會涉及頻繁點擊切換路徑的情況,為了防止無謂的重復渲染,給所有presentational components都設置為PureComponent, 接著在一些只需要更新一次的組件里手寫shouldComponentUpdate, 還是強調一點: 必須十分清楚傳入的參數,以及其結構,并考慮這個結構是否在生產環境中有變化的可能導致判斷失效。 還有個值得注意的問題是react-router-v4里的NavLink檢測location渲染當前激活地址的link(activeClassName屬性)時,注意組件是否是PureComponent, 如果是,必須在父組件傳入location,否則PureComponent的shouldComponentUpdate將會判定參數無變化,從而block掉link的動態渲染。參照: Dealing with Update Blocking
Server Side: 由于是使用leancloud部署,用node環境,為了解決v2ex api的跨域問題,自己寫了一套請求轉發,但是問題來了: 單頁APP里為保證刷新后不出現cannot get等問題,必須寫上一條app.get("*", (req, res) => {res.sendFile("index.html的路徑")} ), 這就很麻煩了,后來經過請教,用正則過濾了請求轉發涉及的路徑,就避免了路徑全局攔截。但是! 這樣刷新后,又會遇到cannot get的問題了。 因為再次刷新時url已經變化,瀏覽器會去請求這個地址,而后臺并沒有提供此路徑的響應。 最好的辦法是使用nginx部署環境。(express難道就沒辦法? 還是我服務端知識短淺啊...要惡補) 另外一個問題: 生產環境和部署環境下由于使用了不同的請求地址,返回的數據的結構存在微小差異,以本項目為例,請求v2ex topic在生產環境下數據是res.data,而到了部署環境下由于使用了自己設置的請求地址,返回的數據成了res.data[0],找了很久才發現問題,值得注意。
Cancellation: 在newsfeed里頻繁切換頁面時還有一個問題: 也許下一個頁面呈現時,上一個頁面中觸發的fetch操作還沒執行完畢。舉個例子: 我進入了v2ex的頁面,此時組件拉取新聞信息,接著我幾乎不等待便切換至github,此時對于v2ex的拉取還在進行。這就是一種浪費了。 為了解決它,起初我嘗試用saga結合react-router-redux里提供的LOCATION_CHANGE action來作為判定取消之前未完成fetch的標志。 測試發現就算我點擊的是同一個link,依然會觸發LOCATION_CHANGE,(真坑啊,完全不符合直覺好么!?)那么有這么一個場景: 當你進入hackerNews等待數據返回,由于時間較久,你不耐煩的再次點擊了hackerNews的Link,Boom~~! LOCATION_CHANGE dispatched. 于是乎你的fetch被取消了...,所以用LOCATION_CHANGE作為判定標志在首次拉取這個場景下是不可行的(論corner case重要性..), 后來想出來的解決辦法是在三塊新聞組件的componentDidMount的頂部dispatch一個STOP_FETCH action,然后將判定取消的標志改為:STOP_FETCH,算是解決了,可總感覺有點暴力,因為一旦組件變多,將要手動。接下來將繼續思考更優雅的解決方案,如果大神們有答案,請告知。
?Gain最大的收獲: 主動找上問題,而不是問題找上你。 不折騰,不踩坑,進步頗微。
當container變多時,直接將container component作為單位,多帶帶設立目錄,然后放置對應的components/styled-components/reducer/action. 這就是按feature組織目錄的方法。 細致的拆分,解耦性更好,以container component為單位進行修改時,大大降低誤傷率的同時,隔離無關的信息。
大概總結出一個Learn by doing的心路歷程:
被未嘗試的技術吸引,并且有了下一個project的idea
嘗試拆分所需技能,分成組塊(裂墻推薦知乎金旭亮老師組塊學習論)
漫長的學習過程: 讀文檔,找樣例,寫小demo倒騰API。由于組塊積累未完全,所以無法對project全面下手,自然會很煩躁,并且踏出了舒適區,接收更多的信息。
組塊知識積累完畢,project開始施工: 從最簡功能需求開始,不斷增加新feature: problem -> google -> resolve.
Project成型,評估,修正,改進,more problem come in.
項目總結。然后享受一下獨立完成project的成就感。同時也會深刻理解自己的不足,為自己的技術精進之路指明了方向。
以project為單位,循環以上步驟。
最后的領悟: 我早幾年干什么去了... 捶胸淚目ing。
??More Feature?未來可能會補上的:
白噪音組合播放
番茄鐘
音樂部分(哈哈哈偷懶了時間不多了,趕緊找工作。)
作為一名新人,還請大家多多指教。同樣無恥的求star,2333。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/83415.html
摘要:不斷更新筆記效果有待進一步完善搭建一個基于的多人功能登錄注冊上傳頭像發表博文發表留言參考自前端部分以的腳手架搭起的全家桶后端采用開發環境開發環境要求以上目錄結構如何運行后端默認配置在中請確保本地端口默認可用發布到目錄中默 Full-stack-blog(不斷更新筆記) 效果Demo(有待進一步完善)搭建一個基于Koa2的多人blog功能(登錄注冊上傳頭像,發表博文,發表留言)參考自ht...
摘要:基于的版本和編寫的模仿原生應用的源碼地址歡迎項目演示地址建議直接添加到主屏幕端體驗差一些前言為什么做這個項目學習全家桶,很長一段時間在用。作者聲稱之后增強了對的支持,探究在中的支持情況。 vue-ts-daily 基于Vue.js的2.5.13版本和TypeScript編寫的模仿原生應用的WebApp.源碼地址 歡迎star 項目演示地址 showImg(https://segment...
摘要:引言兩個月前用全家桶實現過一次酷狗音樂,最近又用全家桶重構了下,最終成果和的實現基本一致,放個圖手機預覽戳版本版本。的行為結構表現分離,很明顯,而的分離雖然不是很明顯,但實際上也是有的。發送指令,最終會到里合并數據,與中的類似。 引言 兩個月前用 Vue 全家桶實現過一次 酷狗音樂,最近又用 React 全家桶重構了下,最終成果和 Vue的實現基本一致,放個圖: showImg(htt...
摘要:地址語言中文可能是目前最用心收集的優秀開源項目大全。地址語言中文匯集了各類學習資料工具組件開源資源下載以及相關新聞等,只求精不求全。地址語言中文優秀博客,以及優秀的庫列表很多英文資料源自于地址語言中文 本文原創首發于公眾號:ReactNative開發圈,轉載需注明出處。 showImg(https://segmentfault.com/img/bVX3Nc?w=480&h=260); ...
閱讀 1437·2021-09-22 15:52
閱讀 1485·2019-08-30 15:44
閱讀 906·2019-08-30 14:24
閱讀 2716·2019-08-30 13:06
閱讀 2712·2019-08-26 13:45
閱讀 2795·2019-08-26 13:43
閱讀 1030·2019-08-26 12:01
閱讀 1457·2019-08-26 11:56