Byemess-基于React&redux的在線Todo應用
為什么又是Todo蝙昙,全世界的初學者都在做todo嗎疗琉?可能很多人要問這句話车遂,其實這句話可以等同于:
- 為什么你做了個云音樂播放器?
- 為什么你做了個新聞閱讀APP?
- 為什么你做了個VUE/REACT版本的CNODE颗胡?
究其本質,這幾個應用都是data-map模式吩坝,哈哈哈哈這是我自己創(chuàng)的詞毒姨,意思就是說,本質都是拿到一組數據钉寝,然后就像遍歷數組一樣將這些數據遍歷渲染手素,這類project都可以算是pure-data-driven的。
至于我為什么做了Todo瘩蚪,答案很簡單,我初學react&redux時接觸的例子就是Todo稿黍,將這個app進行功能拓展疹瘦,將會使用到react和redux的各種特性。
這個App的UI直接參考了知乎@黃玄的Vue寫的TodoApp巡球,已經獲得他本人的許可言沐。設計活兒太磨人,本著熟練react&redux的項目實戰(zhàn)的目的酣栈,UI和交互就沒有想花太多時間去設計险胰,直接照著樣子寫了一個,他的代碼我可一個字都沒看過矿筝,別噴我山寨哈哈哈起便。
源代碼
Github
如果對你有有所啟發(fā)或者幫助,送我一個star吧 :)
已部署版本(2017.05.04更新)
heroku國內太卡了窖维,還是直接用了Leancloud榆综。
點這里點這里:Byemess
預覽
Login
Logged
Main
Add Todo
Responsive
Drawer
哈哈哈用drawer來插入一下自我推廣的信息貌似是常用套路?主要的頁面導航使用bottomBar去切換铸史,這樣切換起來更加方便鼻疮。
目錄結構
標準目錄結構,有兩個地方提一下:
styled 用來存儲所有經過styled-components進行裝飾后的組件琳轿,清一色presentational components判沟,所以移入components目錄下是沒有問題的,但考慮到它的feature崭篡,在項目存在潛在規(guī)模擴大可能時挪哄,通過Feature進行分類更好,所以就沒有進行合并琉闪。
對于components 和 container的分類市面上真是五花八門中燥,對我而言,我更傾向跟隨redux作者(真是帥疤临恕)的定義:
It's up to whether the component is aware of Redux
疗涉,通俗點說拿霉,不需要connect至store的組件都不是container. 這樣的確make sense, 不過在組件的分配上會顯得有點奇怪咱扣,這就比較考功力和經驗了绽淘。
Function
- Single Page App
- 在線注冊賬號,數據存儲于leanCloud闹伪。
- todoItem增刪改沪铭,數據同步到云
- 根據完成情況切換視圖
- 添加日期標簽,所有item按日期分組
TechStack
- React: 全套ES6及以上語法偏瓤,生命周期函數杀怠,ref操作,動態(tài)渲染厅克,應有盡有赔退。
- Redux: 采用最佳實踐,針對不同的邏輯state管理進行拆分证舟,然后combine之. 采用Thunk處理Action硕旗,控制異步操作。
- React-Routerv4:跟以前的版本有顯著變化女责,構建單頁APP利器漆枚。
- Styled-Components: 強推,什么BEM抵知,什么CSS-Module墙基,通通靠邊,結合Helper: Styled-props刷喜,徹底解決css組件化方案碘橘。告別預處理器,避免創(chuàng)造更多學習成本吱肌。
- Webpack: 自動化構建痘拆,采用chunkhash方式分類打包文件,優(yōu)化用戶緩存策略氮墨。
- CSS3: 結合CSSTransitionGroup纺蛆,創(chuàng)建組件過場動畫,優(yōu)化體驗规揪。
- underscore: 用它還是用lodash都行桥氏,我只是需要用一下里面的debounce,用來控制edit todoItem時API通信的頻率猛铅。其實自己手寫一個helper也行字支,在學習redux的練手項目里我就手寫= = 。
后續(xù)可能優(yōu)化使用的:
- reselect: 再也不用手寫那么多重復的state selector了!
- immutable: 感受函數式的威力堕伪。
- redux saga: 2017年了揖庄,還不使用generator的異步action控制體系。
Problem
state
的設計主要針對數據的獲取與查找策略欠雌,模擬數據庫的方式蹄梢,建立LookupTable
,存儲目標id富俄,遍歷id進行數據拉取禁炒。這樣的方式好處是在分狀態(tài)顯示todoItems時只需要操作id,而不需要操作數據實體霍比,提高性能幕袱。 但是同時也遇到一個問題: 針對查找策略對應確定的api層構造相對耦合,數據拉取方式無法本地模仿悠瞬,因此讓我放棄了使用LocalStorage
的進行離線狀態(tài)的支持们豌。 黃玄的策略是優(yōu)先進行本地操作,用戶可以選擇上傳或者下載數據阁危,這個方式不錯,對我有所啟發(fā)汰瘫。 過度對數據模型進行裝飾的結果便是高耦合狂打,這跟我初衷是基于在線存儲數據有關。 算是一個教訓混弥。之前想要給登錄成功頁面添加延時跳轉的功能趴乡,以便使用戶體驗更加完整,但是嘗試未果蝗拿,原因是login頁面和list頁面本質上是兩個
route
下的組件晾捏,進行切換時會進行拉取數據 =>Re-render
,一旦我登錄后再次進入login頁面哀托,無論我在login組件里如何嘗試記錄上一次的狀態(tài)進行比對(componentWillReceiveProps
)惦辛,都是徒勞。 后來想到根目錄下App組件可以進行connect保存一個登錄的flag仓手,以此來確保第一次從未登錄狀態(tài)進入登錄狀態(tài)時時才會進行跳轉胖齐。但是我沒有這樣做,我實在不想污染APP這個root組件嗽冒,除非再包一層...跳轉部分React-router并沒有提供更多API呀伙,其
Redirect
的時間上的可操控性不高,只能依賴注入BrowserHistory
屬性來進行人工push地址添坊,略為丑陋剿另。鄙人才疏學淺,相信不久后能找到更優(yōu)雅的方式。
總結
我的不足
耗費時長:從學習React&Redux開始雨女,花費了相對較多的時間在學習相關的綜合知識(組件設計谚攒,結構設計,reducer戚篙,action的結構最佳實踐等等)五鲫,使得我的項目遲遲未能開工,個人可能更習慣有所深度的學習后再進行實踐岔擂,也是貪了想少走彎路的念頭位喂。然后習慣性被炫酷的技術吸引,研究了兩天react-motion(膜拜@chengmo大神啊乱灵,咱們中國小伙有智慧)塑崖,因為當時想要實現drag Sortable List的效果,后來回過神來痛倚,先做出基本再說规婆!這個APP從做出原型到重構修改總工時粗略計算大概不到8天期間穿插各種亂七八糟的探索,如果擼起袖子直接干蝉稳,應該可以壓縮到6天抒蚜。當然了學習成本不可忽略,我給自己的時長計算時從0了解到輸出成品耘戚。
App效果: 給自己打7分嗡髓,可優(yōu)化拓展的東西太多。還記得我說的
data-map
模型嗎收津?我完全可以把這個App打造成一個工作臺饿这,把之前那些滿地飛的項目都囊括進來,可以加大練習技術的力度撞秋,這樣我就可以終結滿知乎鬧的什么“為何vue的demo比react多”之類的無聊話題长捧,純屬Vue好上手!文檔親切直白如私教吻贿!各大中文網示例重構demo多到不行好嗎串结!光是react這英文環(huán)境就夠國內60%程序猿吃一壺了。(扯遠了哈哈哈)
夸夸自己
-
及時總結: 學習的時候容易懵逼容易記憶斷片怎么辦>肆小奉芦?這一度讓我很苦惱,為了加速學習進程剧蹂,唯有: 總結声功!梳理!寫博客宠叼!于是誕生了這倆貨:(新手朋友們看一看對概念原理理解一定會有幫助)
自學上手效率: 曾經一度不是很自信先巴,當然了都是老大徒傷悲云云其爵,對自己的真實實力還是有一定自信,我相信我能夠短時間接受并運用甚至拓展所學知識伸蚯,我也的確做到了摩渺。由于一開始便對react有迷之好感(這輩子第一次對一個技術生態(tài)有這種感覺),加上自己英語無壓力剂邮,閱讀了許多關于react技術棧的文章摇幻,了解了刀耕火種到現在一片大繁榮的react體系下的技術變遷,對知識體系有了一個宏觀的把控挥萌,這個階段大概一周绰姻,期間還看著網上的教程寫了幾個小demo用來針對訓練一些技術點:比如
父子雙向通信
,生命周期函數使用場景
引瀑,異步action處理方案
狂芋,模擬redux內部核心功能
:github(1),github(2)憨栽。 我個人的思維很發(fā)散帜矾,容易噼里啪啦想到很遠很歪,導致了以前學習過程中缺乏統一的節(jié)奏屑柔,一下搗鼓一下動畫隊列屡萤,一下看看源碼,沒有很持久的去做一件事掸宛,這次算是圓滿啦死陆。不過這次能上手這么快,也得益于以前javascript的基礎旁涤,細節(jié)不保證全部能回憶翔曲,但是思想和經驗都沉淀進了自己的腦子迫像,接下來要去找工作劈愚,還得把基礎好好過一遍,重中之重闻妓!解決實際問題的能力: 現在自己解決問題的感覺越來越好菌羽,可以快速定位問題的癥結,擅用搜索引擎(我真的好久好久沒有用過baidu了...)由缆,specific的問題會一股腦先用文字輸出的形式描述一遍注祖,這樣讓問題的結構在腦中有個印象,然后過一會兒回來自己就萌發(fā)idea均唉,然后嘗試 -> 解決是晨。 最后一句: 靠自己。