前言:本來(lái)有幾個(gè)圖,不貼是因?yàn)槭蔷W(wǎng)圖侵權(quán)了锨侯。
首先create-react-app
這是facebook react官方提供的一個(gè)nodejs(npm/yarn/cnpm)命令冶匹。用于創(chuàng)建react start工程比庄。
- 創(chuàng)建好的工程包括:基礎(chǔ)的已經(jīng)配置好的npm配置文件。以及簡(jiǎn)單的樣例代碼和文件結(jié)構(gòu)韭脊。
- 查看npm配置文件package.json:工程依賴(lài)的包掸鹅、啟動(dòng)塞帐、編譯等:依賴(lài)于react-script(一個(gè)js庫(kù)/js命令)
- 進(jìn)而看react-script (node_modules中):
3.1 它包括已配置好的webpack配置文件
3.2 各個(gè)啟動(dòng)命令參數(shù)對(duì)應(yīng)的nodejs代碼實(shí)現(xiàn)
3.3 解讀各個(gè)命令 & 解讀webpack配置文件:
3.3.1 start命令----用nodejs啟動(dòng)web服務(wù),事實(shí)上是啟動(dòng)了webpack的WebpackDevServer 河劝”陂牛【個(gè)人理解:server啟動(dòng)后,這個(gè)前端應(yīng)用服務(wù)器會(huì)根據(jù)webpack的配置赎瞎,對(duì)我們自己的工程代碼進(jìn)行預(yù)處理,并發(fā)布到web服務(wù)颊咬。我們?cè)跒g覽器調(diào)試中看到的已發(fā)布的前端應(yīng)用务甥,實(shí)際上是實(shí)時(shí)處理后的結(jié)果。實(shí)時(shí)處理依據(jù)的處理原則:應(yīng)該參見(jiàn)webpack的配置文件喳篇。
3.3.2 build命令----在工程中生成build目錄敞临,并將處理后的文件發(fā)布到該目錄下◆锢剑【根據(jù)webpack配置挺尿,該目錄下的代碼是經(jīng)過(guò)babel處理、壓縮過(guò)后的炊邦。那如果使用sass编矾,還可以將sass處理步驟配置到webpack配置文件中,在build時(shí)一并處理】【從這個(gè)角度來(lái)看馁害,我認(rèn)為可以將webpack類(lèi)比為java中的ant
3.4 到這里我們會(huì)發(fā)現(xiàn)窄俏,react-script和react本身的關(guān)系不大〉獠耍看上去它僅僅是將webpack進(jìn)行了封裝凹蜈。那么限寞,它究竟包含了什么?看一下package.json
3.4.1 webpack仰坦、babel履植、eslint(靜態(tài)檢查)等
3.4.2 react的dev tools等。
3.4.3 另外悄晃,react-script還設(shè)置了REACT相關(guān)的環(huán)境變量静尼。
3.5 因此,整個(gè)react-script传泊,我認(rèn)為是一個(gè)類(lèi)ant工具(webpack) + 配置好了的基礎(chǔ)依賴(lài)和基礎(chǔ)配置文件鼠渺。
3.6 因此,對(duì)于有了react-script這種工具的我們來(lái)說(shuō)眷细,其實(shí)整個(gè)工程中的V部分拦盹,是不是react并不重要,也可以是vue與它的一些周邊庫(kù)溪椎。 - 回到create-react-app普舆,進(jìn)入source,可以看到基礎(chǔ)的react樣例代碼校读≌勇拢可以以此為基礎(chǔ)進(jìn)行開(kāi)發(fā)了。它只有最基本的代碼部分歉秫,但是調(diào)試蛾洛、編譯環(huán)境、配置雁芙,已經(jīng)為我們搭建好轧膘。
- 我們還是缺少最佳實(shí)踐:如何組織目錄結(jié)構(gòu)進(jìn)行基于react的前端spa開(kāi)發(fā)?怎么實(shí)現(xiàn)MVC兔甘?等等谎碍。
Redux
0.1 說(shuō)Redux之前,還是先總結(jié)一下React洞焙。React的語(yǔ)法不用多說(shuō)蟆淀。而React的定位,簡(jiǎn)單來(lái)說(shuō)是利用JSX實(shí)現(xiàn)了可以js和xml混寫(xiě)澡匪,實(shí)現(xiàn)了用JS對(duì)象渲染前端界面的組件化開(kāi)發(fā)思想熔任。
0.2 目前,前端技術(shù)的主流思想是仙蛉,利用ES新語(yǔ)法進(jìn)行整個(gè)前端單頁(yè)的開(kāi)發(fā)笋敞。 最新語(yǔ)法帶來(lái)的好處是代碼簡(jiǎn)化、api豐富荠瘪、可讀性高等夯巷。配合babel實(shí)現(xiàn)發(fā)布前的預(yù)處理(因?yàn)楹苓z憾赛惩,主流瀏覽器現(xiàn)在一般對(duì)js僅支持到ES5),我們可以使用高級(jí)語(yǔ)法為我們帶來(lái)拳拳到肉的編碼爽快感趁餐,而無(wú)需在意其它喷兼。
0.3 React提供大量而完善周邊庫(kù)實(shí)現(xiàn)如:路由、http請(qǐng)求后雷、ui特效等一些前端工程所需要的功能季惯。Redux就是其中一個(gè)很重要的庫(kù)。利用它可以更好地實(shí)現(xiàn)SPA臀突。
- Redux【 當(dāng)然還有 Flux勉抓、Reflux、Mobx 等狀態(tài)管理庫(kù)可供選擇】候学∨航睿基礎(chǔ)核心思想是實(shí)現(xiàn)狀態(tài)管理∈崧耄【Redux 莞式教程】
- Redux可以不和react配合使用隐圾,它可以?xún)H作為一個(gè)狀態(tài)管理庫(kù)£瑁【深入理解React Redux】
- 進(jìn)階暇藏。react-redux【Redux管理你的React應(yīng)用】
- 一個(gè)重要的細(xì)節(jié):在概念上,React組件中都包含一個(gè)props對(duì)象濒蒋,可以用它來(lái)放組件的屬性等盐碱。(這是React中的一個(gè)重要思想,但在VUE的設(shè)計(jì)思想上并沒(méi)有這個(gè)概念)啊胶。而react-redux則提供了如何將Redux的狀態(tài)管理和React的props結(jié)合的解決方案甸各。
好,我們開(kāi)始Redux焰坪。
Redux 的設(shè)計(jì)思想很簡(jiǎn)單,就兩句話聘惦。 是阮一峰告訴我們的【阮一峰Redux入門(mén)教程】
(1)Web 應(yīng)用是一個(gè)狀態(tài)機(jī)某饰,視圖與狀態(tài)是一一對(duì)應(yīng)的。
(2)所有的狀態(tài)善绎,保存在一個(gè)對(duì)象里面黔漂。
大神關(guān)于Redux文章一共寫(xiě)了三部曲,下面解讀阮一峰Redux三部曲:
三部曲之(一)的思想總結(jié):
- store整個(gè)應(yīng)用唯一禀酱。
- store中有state炬守,它對(duì)應(yīng)當(dāng)前應(yīng)用的狀態(tài),因此當(dāng)前應(yīng)用只會(huì)有一個(gè)唯一狀態(tài)剂跟。因此减途,就能確定的當(dāng)前的VIEW是什么酣藻。
- 當(dāng)store進(jìn)行dispatch的時(shí)候,入?yún)⑹莂ction(或者 action creator)鳍置。執(zhí)行完了dispatch辽剧,新的state就有了。所以税产,這時(shí)候VIEW就該變化了怕轿。所以,VIEW本身做實(shí)現(xiàn)的時(shí)候辟拷,就是根據(jù)state的不同撞羽,來(lái)呈現(xiàn)不同的樣貌即可。而VIEW的開(kāi)發(fā)實(shí)現(xiàn)利用REACT本身就行衫冻。
- 但是VIEW會(huì)自動(dòng)變化嗎诀紊?顯然不會(huì)。我們需要給store注冊(cè)一個(gè)監(jiān)聽(tīng)器羽杰,state發(fā)生變化的時(shí)候渡紫,系統(tǒng)就會(huì)調(diào)用這個(gè)監(jiān)聽(tīng)器。我們?cè)谶@個(gè)監(jiān)聽(tīng)器里調(diào)用比如說(shuō)全局視圖刷新方法考赛,就可以了惕澎。
- 如何根據(jù)action的不同,來(lái)變更state颜骤?靠的是reducer唧喉。因?yàn)槿志鸵粋€(gè)store,因此僅有一個(gè)reducer忍抽。但是八孝,在實(shí)際的系統(tǒng)中,action會(huì)非常多鸠项,所以state也會(huì)千變?nèi)f化干跛,所以由action來(lái)變化state會(huì)有各種邏輯。因此:reducer也會(huì)非常龐大祟绊。所以楼入,reducer在開(kāi)發(fā)的時(shí)候,是可以拆開(kāi)開(kāi)發(fā)的牧抽,然后可以組合起來(lái)嘉熊,這是Redux提供的api支持的。
- state僅僅是一個(gè)值嗎扬舒?不阐肤。它是一個(gè)對(duì)象,或者說(shuō)是很多值的集合。而在我們?cè)O(shè)計(jì)reducer的時(shí)候----開(kāi)發(fā)實(shí)現(xiàn)的原則是:一個(gè)action過(guò)來(lái)孕惜,只改變state的部分屬性愧薛。這也是reducer可以拆分的原因。
綜述:Redux的哲學(xué)诊赊。
三部曲之(二)的思想總結(jié):(可以先跳過(guò))
- 中間件是什么厚满?它重寫(xiě)了store.dispatch(action)方法,或者說(shuō)在這個(gè)方法外面又包裝了一層碧磅。即接收到action了碘箍,調(diào)用真正的store.dispatch(action)----(實(shí)際上這個(gè)api中就是redux幫我們?nèi)?zhí)行reducer方法嘛)前后加入一些邏輯【ń迹【中間件的洋蔥模型】
- 我們沒(méi)有必要自己實(shí)現(xiàn)中間件丰榴,redux里有些現(xiàn)成的好用的中間件可以拿來(lái)用的。
- redux中提供了一些中間件秆撮,如redux-logger四濒,它肯定意思就是在dispatch的時(shí)候打日志嘛。它怎么用职辨?在創(chuàng)建store的時(shí)候(createStore)盗蟆,apply(redux的api)一下它,就可以了舒裤。但是喳资,注意多個(gè)中間件apply的時(shí)候次序很重要。
- 有了中間件腾供,就可以搞異步操作了(在實(shí)現(xiàn)reducer時(shí)仆邓,你要寫(xiě)所謂的“純函數(shù)”,這是規(guī)定伴鳖,因?yàn)閞educer是要更新state的节值,不能有異步操作)。什么情況下我們需要異步操作榜聂?比如請(qǐng)求數(shù)據(jù):需要等待數(shù)據(jù)返回搞疗,然后返回成功以后怎樣怎樣,返回失敗以后怎樣怎樣须肆。這里請(qǐng)求數(shù)據(jù)是一個(gè)action贴汪,然后請(qǐng)求成功異步觸發(fā)一個(gè)action,失敗一個(gè)action休吠。好,你說(shuō)你自己寫(xiě)邏輯來(lái)處理业簿,沒(méi)問(wèn)題瘤礁。無(wú)非整個(gè)過(guò)程就是:請(qǐng)求開(kāi)始,發(fā)出第一個(gè)action梅尤,state變?yōu)檎谡?qǐng)求狀態(tài)柜思,view渲染岩调,然后等著請(qǐng)求結(jié)束時(shí)候,發(fā)出另一個(gè)action赡盘,state變成操作結(jié)束狀態(tài)号枕,view再次渲染。
- 你想等請(qǐng)求結(jié)束的時(shí)候陨享,自動(dòng)觸發(fā)發(fā)出第二個(gè)action葱淳?我知道你自己會(huì)寫(xiě)js實(shí)現(xiàn)。但是你可以嘗試一下redux-thunk中間件抛姑。
- 上文我們提到過(guò)action creator赞厕。它是一個(gè)函數(shù),返回一個(gè)action對(duì)象定硝。使用redux-thunk中間件皿桑,就可以讓store.dispatch入?yún)⑹且粋€(gè)action creator方法(本身)。然后這個(gè)action creator的入?yún)⒂衐ispatch蔬啡。這樣你就可以在creator中調(diào)用多次dispatch了诲侮。【我也不是特別理解】
7.使用promise箱蟆。利用action creator返回一個(gè)promise對(duì)象沟绪、或者返回一個(gè)包含promise對(duì)象的action。然后利用promise中間件顽腾。在promise對(duì)象中搞異步操作即可近零。【我也不是特別理解】
綜述:中間件的哲學(xué)抄肖。
三部曲之(三)的思想總結(jié):
- React-Redux久信。需要我們將組件進(jìn)行區(qū)分,分成兩類(lèi)漓摩。UI和容器裙士。
- UI組件:傳統(tǒng)的React組件。特點(diǎn):負(fù)責(zé)UI呈現(xiàn)管毙。沒(méi)有狀態(tài)腿椎,即沒(méi)有this.state。數(shù)據(jù)由this.props提供夭咬。不使用任何Redux的API啃炸。
- 容器組件:特點(diǎn)恰恰相反。負(fù)責(zé)邏輯卓舵、有狀態(tài)南用、用Redux API。
- React-Redux 規(guī)定,所有的 UI 組件都由用戶(hù)提供裹虫,容器組件則是由 React-Redux 自動(dòng)生成(connect)肿嘲。【connect方法常見(jiàn)寫(xiě)法后面有兩個(gè)括號(hào)的問(wèn)題筑公,請(qǐng)看這個(gè)解讀】
- 有了UI組件雳窟,則可生成對(duì)應(yīng)的容器組件了。那么匣屡,state如何轉(zhuǎn)變?yōu)閁I組件的參數(shù)封救?用戶(hù)在UI上的行為,如何轉(zhuǎn)換成redux的action耸采?因此兴泥,由UI生成對(duì)應(yīng)的容器的時(shí)候,需要實(shí)現(xiàn)兩個(gè)方法:mapStateToProps和mapDispatchToProps虾宇。
- mapStateToProps入?yún)⑹莝tate搓彻,返回一個(gè)對(duì)象。它會(huì)訂閱store嘱朽!當(dāng)state有變化時(shí)重新渲染UI????
- mapDispatchToProps可以是一個(gè)方法旭贬,也可以是一個(gè)對(duì)象。如果是函數(shù)搪泳,入?yún)⑹莇ispatch和props稀轨。
- Provider。采用上面的方式的話岸军,容器組件需要能或得到store才行奋刽,怎樣才能有?利用Provider在根組件上包一層艰赞,將store給它佣谐!【看到這里,我們終于可以看明白react-demo留言板的入口代碼了】
- 《七方妖、實(shí)例:計(jì)數(shù)器》
- 所以狭魂,組織SPA VIEW整體架構(gòu)或者路由等的時(shí)候,用外層的容器組件就好了党觅。
綜述:Redux和React結(jié)合起來(lái)做SPA時(shí)的哲學(xué)雌澄。
Redux總復(fù)習(xí):可以看【Redux的全家桶與最佳實(shí)踐】
react-router
- 路由與單頁(yè)應(yīng)用的關(guān)系:我的理解:?jiǎn)雾?yè)應(yīng)用即整個(gè)頁(yè)面不刷,僅局部刷杯瞻。但是頁(yè)面中的按鈕镐牺、超鏈接仍是地址
<a href="#/xxxUrl">
。在這個(gè)例子中魁莉,我們知道#的這種地址是不會(huì)觸發(fā)瀏覽器頁(yè)面跳轉(zhuǎn)的任柜。路由的概念在這里實(shí)現(xiàn):通過(guò)判斷地址卒废,頁(yè)面中的組件(react組件)進(jìn)行重新渲染時(shí),根據(jù)地址的不同宙地,渲染結(jié)果也不同。通過(guò)這種機(jī)制實(shí)現(xiàn)頁(yè)面局部變化逆皮≌啵【react-router簡(jiǎn)介 --這個(gè)已經(jīng)語(yǔ)法過(guò)時(shí)了,進(jìn)去以后參看英文原版电谣。前端的語(yǔ)法更新?lián)Q代非郴嗝罚快】 - 因此,react-router將路由簡(jiǎn)化成path和Component(通過(guò)與Redux結(jié)合使用剿牺,我們知道企垦,這個(gè)組件其實(shí)是容器組件)的映射關(guān)系。
- 整個(gè)spa就都交給router來(lái)渲染就行了晒来,因?yàn)閞outer不僅維護(hù)了這個(gè)映射關(guān)系钞诡,還具備了渲染能力????
- router屬于MVC的C嗎????
- redux屬于MVC的C嗎????
- (這段后來(lái)加的)3 4 5是我曾經(jīng)疑惑的問(wèn)題。到現(xiàn)在的理解:所謂渲染和呈現(xiàn)湃崩,其實(shí)是V的部分荧降,那V的部分肯定是React本身。那攒读,呈現(xiàn)哪些東西朵诫,肯定是React組件根據(jù)props確定的。那么如何生成props薄扁?我理解是通過(guò)router啦剪返,通過(guò)redux啦,這些手段一步步地來(lái)保證最后V的生成邓梅⊥衙ぃ可以看這張圖示來(lái)理解整個(gè)流程。因此震放,誰(shuí)是C宾毒,這個(gè)不好說(shuō)。但是可以肯定的是殿遂,在最佳實(shí)踐中诈铛,React組件是V。但是組件中會(huì)定義一些動(dòng)作觸發(fā)的事件墨礁,在事件觸發(fā)時(shí)生成action并做一些dispatch的調(diào)用幢竹。Model(dva中的概念)顧名思義肯定是M,但是它中還定義了監(jiān)聽(tīng)恩静、定義了reducer焕毫、定義了effects等等蹲坷。那到底怎么界定C?或者說(shuō)前端框架就沒(méi)有C邑飒?或者它就是傳說(shuō)中的MVP或者M(jìn)VVM循签?
視頻教程
弄懂了以上這些,可以看視頻教程了疙咸。請(qǐng)注意如果上面這些沒(méi)弄懂县匠,看視頻教程可能是一臉懵逼的。
看哪個(gè)視頻教程呢撒轮?正巧我這里有個(gè)視頻教程乞旦,認(rèn)識(shí)的人可以管我要,不公開(kāi)發(fā)出來(lái)是因?yàn)榍謾?quán)题山±挤郏或者你可以看它的優(yōu)酷版本(不過(guò)優(yōu)酷版本錄得不好)
好了,找個(gè)例子顶瞳,你可以研究源碼了
react-demo(留言板)
react-sagas
這一段也是我后來(lái)加的玖姑。你可以先看完中間件的解讀,再反過(guò)頭來(lái)看這個(gè)庫(kù)浊仆。因?yàn)樗昧酥虚g件的原理客峭。
簡(jiǎn)單來(lái)說(shuō),reducer必須是純函數(shù)抡柿。那么如果有異步處理舔琅,用reducer就不能做了,因此可以使用effect的方式來(lái)做洲劣。用effect方法代替reducer备蚓。這種effect的方式,正是sagas提供的囱稽。
資料鏈接:Dva中對(duì)effects的理解和使用 && DVA中的技術(shù)概念郊尝,可以直接看Effect部分 && redux-saga 實(shí)踐總結(jié) && redux-sagas異步操作 && Redux-saga 中文文檔
從技術(shù)層面,effect方法并不是普通方法战惊,應(yīng)是構(gòu)造器方法(ES6)流昏。
我的理解,以上吞获。