react剛剛推出的時(shí)候,講react優(yōu)勢(shì)搜索結(jié)果是幾十頁。
10年積累的網(wǎng)站制作、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有陽江免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。現(xiàn)在,react已經(jīng)慢慢退火,該用用react技術(shù)棧的已經(jīng)使用上,填過多少坑,加過多少班,血淚控訴也不下千文。
今天,再談一遍react優(yōu)勢(shì),WTF?
React的收益有哪些?React的優(yōu)勢(shì)是什么?react和vue、angularJS等其它框架對(duì)比優(yōu)勢(shì)?
而作為總結(jié)回顧。react在工程實(shí)踐中,帶來哪些思想上的質(zhì)變?
virtual dom虛擬DOM概念
它并不直接對(duì)DOM進(jìn)行操作,引入了一個(gè)叫做virtual dom的概念,安插在javascript邏輯和實(shí)際的DOM之間,好處是減少DOM操作,減少DOM操作的目的是提高瀏覽器的渲染性能。
虛擬dom就中小型項(xiàng)目而言,的確從表象上看不出太多的優(yōu)勢(shì),因?yàn)樗鉀Q的是底層的dom渲染,IO開銷問題。但是想想facebook的體量,不難猜出react的誕生是為了解決更復(fù)雜更大型的項(xiàng)目開發(fā)和管理的。
實(shí)際上React和Vue其實(shí)也在操作DOM,只是比較高效地在操作DOM而已,虛擬DOM其實(shí)最終也會(huì)映射到真實(shí)DOM,雖然虛擬DOM只會(huì)將變化的部分更新到真實(shí)DOM,但實(shí)際上直接操作DOM也可以通過某些方式去優(yōu)化,那么:
1、操作data,不直接操作DOM有什么好處?
更少的代碼做更多的事。
2、操作data會(huì)給DOM操作帶來什么不好的地方嗎?
不會(huì),但是不是所有功能“使用操作data”都可以代替的。
3、會(huì)不會(huì)比直接操作DOM存在什么難度?
不會(huì)有難度,但是思維需要有一些轉(zhuǎn)變。
JSX雖然做了抽象視圖,但她是聲明式API,能夠保證你看一眼就知道組件樹的結(jié)構(gòu),譬如:
這結(jié)構(gòu)還算清楚吧,基本一眼就知道這個(gè)一個(gè)面板由輸入框、列表、摘要組成,而且布局也清楚了,自上而下。而且,通過查看一個(gè)源文件就可以知道你的組件將會(huì)如何渲染。這是大的好處,盡管這和 Angular 模板沒什么不同。具體參看:ReactJS For Stupid People
之前寫UI的時(shí)候往往為了性能,要設(shè)計(jì)很多DOM的操作邏輯,用了react之后,這些都不給你做了,由他的state跟props來傳遞給VDOM,很省事,更專注于UI層面。
學(xué)會(huì)了react以及這個(gè)JSX語法,你不光可以通過react寫web;也可以通過react-native寫ios或者android的應(yīng)用;甚至可以通過react-blessed寫terminal可視化應(yīng)用;當(dāng)然也可以通過react-native-desktop寫桌面應(yīng)用。因?yàn)镴SX這種聲明式語法實(shí)際是在構(gòu)建一個(gè)抽象的視圖層,這種抽象可以通過不同適配器適配到各種顯示終端,這總夠?qū)虐桑?/p>
unidirectional data flow-單向數(shù)據(jù)流
React倡導(dǎo)使用flux模式來進(jìn)行組件間數(shù)據(jù)傳輸,這種做法叫unidirectional data flow(單向數(shù)據(jù)流),單向數(shù)據(jù)流的好處是與之前angularJS提出的two-way data binding相比較而言,因?yàn)閱蜗?,所以各種變化都是可預(yù)計(jì)、可控制的。不像two-way data binding那樣,變化一但復(fù)雜起來,大家都互相觸發(fā)變化,到最后一個(gè)地方變了,你根本猜不出來她還會(huì)導(dǎo)致其他什么地方跟著一起變。這個(gè)需要大量實(shí)踐才能有所感受,如果你初學(xué),那聽聽就算了,不必死磕。
react項(xiàng)目結(jié)構(gòu)更加清晰:
virtual dom、redux、action,分部分別存放,就象java寫后臺(tái)查數(shù)據(jù)本來用jdbc一條sql就搞定,但分成action service dao分門別類地存放,這樣維護(hù)性好,大公司的代碼需要規(guī)范,這樣出了問題好找原因。
組件化
一切都是component:代碼更加模塊化,重用代碼更容易,可維護(hù)性高。
這里就涉及到react的 架構(gòu),比如:
smart, dumb component
把組件分成兩大類 Smart Components (容器) & Dumb Components(顆?;M件)
這樣做的好處:
有助理你分離關(guān)注點(diǎn),這樣的話更有助于理解你的app的業(yè)務(wù)邏輯 和 它的ui
更有助于復(fù)用你的dumb組件,你可以將你的dumb組件復(fù)用于別的state下,而且這兩個(gè)state還完全不同
本質(zhì)上dumb 組件 其實(shí) 就是你的app的調(diào)色版。。你可以將它們放到一個(gè)頁面上。。然后讓設(shè)計(jì)師除了app的業(yè)務(wù)邏輯,樣式隨便怎么改,
參看文章:Smart and Dumb Components
高階組件(HOC-higher order component)
高階組件(HOC)是react中對(duì)組件邏輯進(jìn)行重用的高級(jí)技術(shù)。但高階組件本身并不是React API。它只是一種模式,這種模式是由react自身的組合性質(zhì)必然產(chǎn)生的。
具體而言,高階組件就是一個(gè)函數(shù),且該函數(shù)接受一個(gè)組件作為參數(shù),并返回一個(gè)新的組件
const EnhancedComponent = higherOrderComponent(WrappedComponent);
對(duì)比組件將props屬性轉(zhuǎn)變成UI,高階組件則是將一個(gè)組件轉(zhuǎn)換成另一個(gè)新組件。
好處:使用高階組件(HOC)解決交叉問題
參看文章:高階組件
總結(jié)下,看看一個(gè)人的組件化水準(zhǔn),
pure component
functional component
smart, dumb component
higher order component
hoc render hijacking
會(huì)用 props.children React.children cloneElement
提供 instance method
context
并理解react 內(nèi)部實(shí)現(xiàn)原理
懂 setState 是異步的
懂 synthetic event
懂 react-dom 分層和 react 沒有關(guān)系
懂 reconciler
懂 fiber
具體問題如下:
1. 怎么抽象一個(gè)帶搜索,單多選復(fù)合,有請(qǐng)求的 Selector,區(qū)分 smart 和 dumped。如果我再往上加功能,比如 autocomplete 等
2. 怎么實(shí)現(xiàn)對(duì)表單的抽象,數(shù)據(jù)驗(yàn)證怎么統(tǒng)一處理
3. 用 react 來實(shí)現(xiàn)一個(gè)可視化編輯器的引擎,怎么設(shè)計(jì),怎么抽象與 model 的交互,再引入 redux 呢,怎么支持第三方組件熱插拔
4. 用 react 和 redux 模擬多人協(xié)作的 Todo,node 作為后端,怎么設(shè)計(jì)
同構(gòu)、純粹的javascrip
因?yàn)樗阉饕娴呐老x程序依賴的是服務(wù)端響應(yīng)而不是JavaScript的執(zhí)行,預(yù)渲染你的應(yīng)用有助于搜索引擎優(yōu)化。
react一些常見問題:
setState()函數(shù)在任何情況下都會(huì)導(dǎo)致組件重渲染嗎?如果setState()中參數(shù)還是原來沒有發(fā)生任何變化的state呢?
對(duì)setState用得深了,就容易犯錯(cuò),所以我們開門見山先把理解setState的關(guān)鍵點(diǎn)列出來。
setState不會(huì)立刻改變React組件中state的值;
setState通過引發(fā)一次組件的更新過程來引發(fā)重新繪制;
多次setState函數(shù)調(diào)用產(chǎn)生的效果會(huì)合并
setState后,知道reader時(shí),才真正改變state的值
shouldComponentUpdate函數(shù)返回false,因?yàn)楦卤恢袛啵圆徽{(diào)用render,但是React不會(huì)放棄掉對(duì)this.state的更新的,依然會(huì)更新this.state
傳入 setState 函數(shù)的第二個(gè)參數(shù)的作用是什么?
該函數(shù)會(huì)在setState函數(shù)調(diào)用完成并且組件開始重渲染的時(shí)候被調(diào)用,我們可以用該函數(shù)來監(jiān)聽渲染是否完成(一般沒有什么卵用)
調(diào)用 setState 之后發(fā)生了什么?
在代碼中調(diào)用setState函數(shù)之后,React 會(huì)將傳入的參數(shù)對(duì)象與組件當(dāng)前的狀態(tài)合并,然后觸發(fā)所謂的調(diào)和過程(Reconciliation)。經(jīng)過調(diào)和過程,React 會(huì)以相對(duì)高效的方式根據(jù)新的狀態(tài)構(gòu)建 React 元素樹并且著手重新渲染整個(gè)UI界面。在 React 得到元素樹之后,React 會(huì)自動(dòng)計(jì)算出新的樹與老樹的節(jié)點(diǎn)差異,然后根據(jù)差異對(duì)界面進(jìn)行最小化重渲染。在差異計(jì)算算法中,React 能夠相對(duì)精確地知道哪些位置發(fā)生了改變以及應(yīng)該如何改變,這就保證了按需更新,而不是全部重新渲染。
用shouldComponentUpdate做優(yōu)化的意義大嗎?shouldComponentUpdate將帶來可測(cè)量和可感知的提升?
如果不能,那就別用:你可能應(yīng)該避免用它。據(jù)React團(tuán)隊(duì)的說,shouldComponentUpdate是一個(gè)保證性能的緊急出口,意思就是你不到萬不得已就別用它。具體參考:什么時(shí)候使用shouldComponentUpdate方法?
一般情況下setState() 確立后總是觸發(fā)一次重繪,除非在 shouldComponentUpdate() 中實(shí)現(xiàn)了條件渲染邏輯。如果使用可變的對(duì)象,但是又不能在 shouldComponentUpdate() 中實(shí)現(xiàn)這種邏輯,僅在新 state 和之前的 state 存在差異的時(shí)候調(diào)用 setState() 可以避免不必要的重新渲染。
react異步數(shù)據(jù)如ajax請(qǐng)求應(yīng)該放在哪個(gè)生命周期?
對(duì)于同步的狀態(tài)改變,是可以放在componentWillMount,對(duì)于異步的,最好好放在componentDidMount。但如果此時(shí)有若干細(xì)節(jié)需要處理,比如你的組件需要渲染子組件,而且子組件取決于父組件的某個(gè)屬性,那么在子組件的componentDidMount中進(jìn)行處理會(huì)有問題:因?yàn)榇藭r(shí)父組件中對(duì)應(yīng)的屬性可能還沒有完整獲取,因此就讓其在子組件的componentDidUpdate中處理。
具體參考:《react異步數(shù)據(jù)如ajax請(qǐng)求應(yīng)該放在哪個(gè)生命周期?》
React 中的 keys 是什么,為什么它們很重要?
在開發(fā)過程中,我們需要保證某個(gè)元素的 key 在其同級(jí)元素中具有唯一性。在 React Diff 算法中 React 會(huì)借助元素的 Key 值來判斷該元素是新近創(chuàng)建的還是被移動(dòng)而來的元素,從而減少不必要的元素重渲染。此外,React 還需要借助 Key 值來判斷元素與本地狀態(tài)的關(guān)聯(lián)關(guān)系,因此我們絕不可忽視轉(zhuǎn)換函數(shù)中 Key 的重要性。
keys 是幫助 React 跟蹤哪些項(xiàng)目已更改、添加或從列表中刪除的屬性。
每個(gè)keys 在兄弟元素之間是獨(dú)一無二的。我們已經(jīng)談過幾次關(guān)于一致化處理(reconciliation)的過程,而且這個(gè)一致化處理過程(reconciliation)中的一部分正在執(zhí)行一個(gè)新的元素樹與最前一個(gè)的差異。keys 使處理列表時(shí)更加高效,因?yàn)?React 可以使用子元素上的 keys 快速知道元素是新的還是在比較樹時(shí)才被移動(dòng)的。
而且 keys 不僅使這個(gè)過程更有效率,而且沒有keys,React 不知道哪個(gè)本地狀態(tài)對(duì)應(yīng)于移動(dòng)中的哪個(gè)項(xiàng)目。所以當(dāng)你 map 的時(shí)候,不要忽略了 keys 。
受控組件( controlled component )與不受控制的組件( uncontrolled component )有什么區(qū)別?
React 的很大一部分是這樣的想法,即組件負(fù)責(zé)控制和管理自己的狀態(tài)(任何改變代用setSate處理)
那么不受控組件呢?組件數(shù)據(jù)不全部是setState來處理,還有DOM交互,比如refs這玩意來操控真實(shí)DOM
雖然不受控制的組件通常更容易實(shí)現(xiàn),因?yàn)槟恍枋褂靡脧腄OM獲取值,但是通常建議您通過不受控制的組件來支持受控組件。
主要原因是受控組件支持即時(shí)字段驗(yàn)證,允許您有條件地禁用/啟用按鈕,強(qiáng)制輸入格式,并且更多的是 『the React way』。
描述事件在React中的處理方式
為了解決跨瀏覽器兼容性問題,您的 React 中的事件處理程序?qū)鬟fSyntheticEvent 的實(shí)例,它是 React 的瀏覽器本機(jī)事件的跨瀏覽器包裝器。
這些 SyntheticEvent 與您習(xí)慣的原生事件具有相同的接口,除了它們?cè)谒袨g覽器中都兼容。有趣的是,React 實(shí)際上并沒有將事件附加到子節(jié)點(diǎn)本身。React 將使用單個(gè)事件監(jiān)聽器監(jiān)聽頂層的所有事件。這對(duì)于性能是有好處的,這也意味著在更新DOM時(shí),React 不需要擔(dān)心跟蹤事件監(jiān)聽器。
在什么情況下你會(huì)優(yōu)先選擇使用 Class Component 而不是 Functional Component?
在組件需要包含內(nèi)部狀態(tài)或者使用到生命周期函數(shù)的時(shí)候使用 Class Component ,否則使用函數(shù)式組件。
簡(jiǎn)單介紹下react的diff
計(jì)算一棵樹形結(jié)構(gòu)轉(zhuǎn)換成另一棵樹形結(jié)構(gòu)的最少操作,是一個(gè)復(fù)雜且值得研究的問題。傳統(tǒng) diff 算法通過循環(huán)遞歸對(duì)節(jié)點(diǎn)進(jìn)行依次對(duì)比,效率低下,算法復(fù)雜度達(dá)到 O(n^3),其中 n 是樹中節(jié)點(diǎn)的總數(shù)。O(n^3) 到底有多可怕,這意味著如果要展示1000個(gè)節(jié)點(diǎn),就要依次執(zhí)行上十億次的比較。這種指數(shù)型的性能消耗對(duì)于前端渲染場(chǎng)景來說代價(jià)太高了!現(xiàn)今的 CPU 每秒鐘能執(zhí)行大約30億條指令,即便是最高效的實(shí)現(xiàn),也不可能在一秒內(nèi)計(jì)算出差異情況。。React 通過制定大膽的策略,將 O(n^3) 復(fù)雜度的問題轉(zhuǎn)換成 O(n) 復(fù)雜度的問題。
react的diff 策略:
Web UI 中 DOM 節(jié)點(diǎn)跨層級(jí)的移動(dòng)操作特別少,可以忽略不計(jì)。
擁有相同類的兩個(gè)組件將會(huì)生成相似的樹形結(jié)構(gòu),擁有不同類的兩個(gè)組件將會(huì)生成不同的樹形結(jié)構(gòu)。
對(duì)于同一層級(jí)的一組子節(jié)點(diǎn),它們可以通過唯一 id 進(jìn)行區(qū)分。
基于以上三個(gè)前提策略,React 分別對(duì) tree diff、component diff 以及 element diff 進(jìn)行算法優(yōu)化,事實(shí)也證明這三個(gè)前提策略是合理且準(zhǔn)確的,它保證了整體界面構(gòu)建的性能。
tree diff:
基于策略一,React 對(duì)樹的算法進(jìn)行了簡(jiǎn)潔明了的優(yōu)化,即對(duì)樹進(jìn)行分層比較,兩棵樹只會(huì)對(duì)同一層次的節(jié)點(diǎn)進(jìn)行比較。
既然 DOM 節(jié)點(diǎn)跨層級(jí)的移動(dòng)操作少到可以忽略不計(jì),針對(duì)這一現(xiàn)象,React 通過 updateDepth 對(duì) Virtual DOM 樹進(jìn)行層級(jí)控制,只會(huì)對(duì)相同顏色方框內(nèi)的 DOM 節(jié)點(diǎn)進(jìn)行比較,即同一個(gè)父節(jié)點(diǎn)下的所有子節(jié)點(diǎn)。當(dāng)發(fā)現(xiàn)節(jié)點(diǎn)已經(jīng)不存在,則該節(jié)點(diǎn)及其子節(jié)點(diǎn)會(huì)被完全刪除掉,不會(huì)用于進(jìn)一步的比較。這樣只需要對(duì)樹進(jìn)行一次遍歷,便能完成整個(gè) DOM 樹的比較。
由此可發(fā)現(xiàn),當(dāng)出現(xiàn)節(jié)點(diǎn)跨層級(jí)移動(dòng)時(shí),并不會(huì)出現(xiàn)想象中的移動(dòng)操作,而是以 A 為根節(jié)點(diǎn)的樹被整個(gè)重新創(chuàng)建,這是一種影響 React 性能的操作,因此 React 官方建議不要進(jìn)行 DOM 節(jié)點(diǎn)跨層級(jí)的操作。
提示:在開發(fā)組件時(shí),保持穩(wěn)定的 DOM 結(jié)構(gòu)會(huì)有助于性能的提升。例如,可以通過 CSS 隱藏或顯示節(jié)點(diǎn),而不是真的移除或添加 DOM 節(jié)點(diǎn)。
component diff:
如果是同一類型的組件,按照原策略繼續(xù)比較 virtual DOM tree。
如果不是,則將該組件判斷為 dirty component,從而替換整個(gè)組件下的所有子節(jié)點(diǎn)。對(duì)于同一類型的組件,有可能其 Virtual DOM 沒有任何變化,如果能夠確切的知道這點(diǎn)那可以節(jié)省大量的 diff 運(yùn)算時(shí)間,因此 React 允許用戶shouldComponentUpdate() 來判斷該組件是否需要進(jìn)行 diff。
如下圖,當(dāng) component D 改變?yōu)?component G 時(shí),即使這兩個(gè) component 結(jié)構(gòu)相似,一旦 React 判斷 D 和 G 是不同類型的組件,就不會(huì)比較二者的結(jié)構(gòu),而是直接刪除 component D,重新創(chuàng)建 component G 以及其子節(jié)點(diǎn)。雖然當(dāng)兩個(gè) component 是不同類型但結(jié)構(gòu)相似時(shí),React diff 會(huì)影響性能,但正如 React 官方博客所言:不同類型的 component 是很少存在相似 DOM tree 的機(jī)會(huì),因此這種極端因素很難在實(shí)現(xiàn)開發(fā)過程中造成重大影響的。
React 提出優(yōu)化策略:允許開發(fā)者對(duì)同一層級(jí)的同組子節(jié)點(diǎn),添加唯一 key 進(jìn)行區(qū)分,雖然只是小小的改動(dòng),性能上卻發(fā)生了翻天覆地的變化!
高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
新聞標(biāo)題:重談react優(yōu)勢(shì)——react技術(shù)棧回顧-創(chuàng)新互聯(lián)
分享鏈接:http://www.rwnh.cn/article34/esise.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、虛擬主機(jī)、靜態(tài)網(wǎng)站、網(wǎng)站導(dǎo)航、標(biāo)簽優(yōu)化、用戶體驗(yàn)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容