做React需要會(huì)什么缚窿?
react的功能其實(shí)很單一丰辣,主要負(fù)責(zé)渲染的功能写烤,現(xiàn)有的框架翼闽,比如angular是一個(gè)大而全的框架,用了angular幾乎就不需要用其他工具輔助配合洲炊,但是react不一樣感局,他只負(fù)責(zé)ui渲染,想要做好一個(gè)項(xiàng)目暂衡,往往需要其他庫和工具的配合询微,比如用redux來管理數(shù)據(jù),react-router管理路由狂巢,react已經(jīng)全面擁抱es6撑毛,所以es6也得掌握,webpack就算是不會(huì)配置也要會(huì)用唧领,要想提高性能藻雌,需要按需加載,immutable.js也得用上斩个,還有單元測(cè)試胯杭。。萨驶。歉摧。
React 是什么
用腳本進(jìn)行DOM操作的代價(jià)很昂貴艇肴。有個(gè)貼切的比喻腔呜,把DOM和JavaScript各自想象為一個(gè)島嶼,它們之間用收費(fèi)橋梁連接再悼,js每次訪問DOM核畴,都要途徑這座橋,并交納“過橋費(fèi)”,訪問DOM的次數(shù)越多冲九,費(fèi)用也就越高谤草。 因此跟束,推薦的做法是盡量減少過橋的次數(shù),努力待在ECMAScript島上丑孩。因?yàn)檫@個(gè)原因react的虛擬dom就顯得難能可貴了冀宴,它創(chuàng)造了虛擬dom并且將它們儲(chǔ)存起來,每當(dāng)狀態(tài)發(fā)生變化的時(shí)候就會(huì)創(chuàng)造新的虛擬節(jié)點(diǎn)和以前的進(jìn)行對(duì)比温学,讓變化的部分進(jìn)行渲染略贮。整個(gè)過程沒有對(duì)dom進(jìn)行獲取和操作,只有一個(gè)渲染的過程仗岖,所以react說是一個(gè)ui框架逃延。
React的組件化
react的一個(gè)組件很明顯的由dom視圖和state數(shù)據(jù)組成,兩個(gè)部分涇渭分明轧拄。state是數(shù)據(jù)中心揽祥,它的狀態(tài)決定著視圖的狀態(tài)。這時(shí)候發(fā)現(xiàn)似乎和我們一直推崇的MVC開發(fā)模式有點(diǎn)區(qū)別檩电,沒了Controller控制器拄丰,那用戶交互怎么處理,數(shù)據(jù)變化誰來管理俐末?然而這并不是react所要關(guān)心的事情愈案,它只負(fù)責(zé)ui的渲染。與其他框架監(jiān)聽數(shù)據(jù)動(dòng)態(tài)改變dom不同鹅搪,react采用setState來控制視圖的更新站绪。setState會(huì)自動(dòng)調(diào)用render函數(shù),觸發(fā)視圖的重新渲染丽柿,如果僅僅只是state數(shù)據(jù)的變化而沒有調(diào)用setState恢准,并不會(huì)觸發(fā)更新。 組件就是擁有獨(dú)立功能的視圖模塊甫题,許多小的組件組成一個(gè)大的組件馁筐,整個(gè)頁面就是由一個(gè)個(gè)組件組合而成。它的好處是利于重復(fù)利用和維護(hù)坠非。
React的 Diff算法
react的diff算法用在什么地方呢敏沉?當(dāng)組件更新的時(shí)候,react會(huì)創(chuàng)建一個(gè)新的虛擬dom樹并且會(huì)和之前儲(chǔ)存的dom樹進(jìn)行比較炎码,這個(gè)比較多過程就用到了diff算法盟迟,所以組件初始化的時(shí)候是用不到的。react提出了一種假設(shè)潦闲,相同的節(jié)點(diǎn)具有類似的結(jié)構(gòu)攒菠,而不同的節(jié)點(diǎn)具有不同的結(jié)構(gòu)。在這種假設(shè)之上進(jìn)行逐層的比較歉闰,如果發(fā)現(xiàn)對(duì)應(yīng)的節(jié)點(diǎn)是不同的辖众,那就直接刪除舊的節(jié)點(diǎn)以及它所包含的所有子節(jié)點(diǎn)然后替換成新的節(jié)點(diǎn)卓起。如果是相同的節(jié)點(diǎn),則只進(jìn)行屬性的更改凹炸。
對(duì)于列表的diff算法稍有不同戏阅,因?yàn)榱斜硗ǔ>哂邢嗤慕Y(jié)構(gòu),在對(duì)列表節(jié)點(diǎn)進(jìn)行刪除啤它,插入饲握,排序的時(shí)候,單個(gè)節(jié)點(diǎn)的整體操作遠(yuǎn)比一個(gè)個(gè)對(duì)比一個(gè)個(gè)替換要好得多蚕键,所以在創(chuàng)建列表的時(shí)候需要設(shè)置key值救欧,這樣react才能分清誰是誰。當(dāng)然不寫key值也可以锣光,但這樣通常會(huì)報(bào)出警告笆怠,通知我們加上key值以提高react的性能。
React組件是怎么來的
組件的創(chuàng)造方法為React.createClass() ——?jiǎng)?chuàng)造一個(gè)類誊爹,react系統(tǒng)內(nèi)部設(shè)計(jì)了一套類系統(tǒng)蹬刷,利用它來創(chuàng)造react組件。但這并不是必須的频丘,我們還可以用es6的class類來創(chuàng)造組件,這也是Facebook官方推薦的寫法办成。
這兩種寫法實(shí)現(xiàn)的功能一樣但是原理卻是不同,es6的class類可以看作是構(gòu)造函數(shù)的一個(gè)語法糖搂漠,可以把它當(dāng)成構(gòu)造函數(shù)來看迂卢,extends實(shí)現(xiàn)了類之間的繼承 —— 定義一個(gè)類Main 繼承React.Component所有的屬性和方法,組件的生命周期函數(shù)就是從這來的桐汤。constructor是構(gòu)造器而克,在實(shí)例化對(duì)象時(shí)調(diào)用,super調(diào)用了父類的constructor創(chuàng)造了父類的實(shí)例對(duì)象this怔毛,然后用子類的構(gòu)造函數(shù)進(jìn)行修改员萍。這和es5的原型繼承是不同的,原型繼承是先創(chuàng)造一個(gè)實(shí)例化對(duì)象this拣度,然后再繼承父級(jí)的原型方法碎绎。了解了這些之后我們?cè)诳唇M件的時(shí)候就清楚很多。
當(dāng)我們使用組件< Main />時(shí)抗果,其實(shí)是對(duì)Main類的實(shí)例化——new Main筋帖,只不過react對(duì)這個(gè)過程進(jìn)行了封裝,讓它看起來更像是一個(gè)標(biāo)簽窖张。
有三點(diǎn)值得注意:1幕随、定義類名字的首字母必須大寫 2蚁滋、因?yàn)閏lass變成了關(guān)鍵字宿接,類選擇器需要用className來代替赘淮。 3、類和模塊內(nèi)部默認(rèn)使用嚴(yán)格模式睦霎,所以不需要用use strict指定運(yùn)行模式梢卸。
react的生命周期
組件在初始化時(shí)會(huì)觸發(fā)5個(gè)鉤子函數(shù):
1、getDefaultProps()
設(shè)置默認(rèn)的props副女,也可以用dufaultProps設(shè)置組件的默認(rèn)屬性蛤高。
2、getInitialState()
在使用es6的class語法時(shí)是沒有這個(gè)鉤子函數(shù)的碑幅,可以直接在constructor中定義this.state戴陡。此時(shí)可以訪問this.props。
3沟涨、componentWillMount()
組件初始化時(shí)只調(diào)用恤批,以后組件更新不調(diào)用,整個(gè)生命周期只調(diào)用一次裹赴,此時(shí)可以修改state喜庞。
4、 render()
react最重要的步驟棋返,創(chuàng)建虛擬dom延都,進(jìn)行diff算法,更新dom樹都在此進(jìn)行睛竣。此時(shí)就不能更改state了晰房。
5、componentDidMount()
組件渲染之后調(diào)用射沟,可以通過this.getDOMNode()獲取和操作dom節(jié)點(diǎn)嫉你,只調(diào)用一次。
在更新時(shí)也會(huì)觸發(fā)5個(gè)鉤子函數(shù):
6躏惋、componentWillReceivePorps(nextProps)
組件初始化時(shí)不調(diào)用幽污,組件接受新的props時(shí)調(diào)用。
7簿姨、shouldComponentUpdate(nextProps, nextState)
react性能優(yōu)化非常重要的一環(huán)距误。組件接受新的state或者props時(shí)調(diào)用,我們可以設(shè)置在此對(duì)比前后兩個(gè)props和state是否相同扁位,如果相同則返回false阻止更新准潭,因?yàn)橄嗤膶傩誀顟B(tài)一定會(huì)生成相同的dom樹,這樣就不需要?jiǎng)?chuàng)造新的dom樹和舊的dom樹進(jìn)行diff算法對(duì)比域仇,節(jié)省大量性能刑然,尤其是在dom結(jié)構(gòu)復(fù)雜的時(shí)候。不過調(diào)用this.forceUpdate會(huì)跳過此步驟暇务。
8泼掠、componentWillUpdate(nextProps, nextState)
組件初始化時(shí)不調(diào)用怔软,只有在組件將要更新時(shí)才調(diào)用,此時(shí)可以修改state
9择镇、render()
不多說
10挡逼、componentDidUpdate()
組件初始化時(shí)不調(diào)用,組件更新完成后調(diào)用腻豌,此時(shí)可以獲取dom節(jié)點(diǎn)家坎。
還有一個(gè)卸載鉤子函數(shù)
11、componentWillUnmount()
組件將要卸載時(shí)調(diào)用吝梅,一些事件監(jiān)聽和定時(shí)器需要在此時(shí)清除虱疏。
以上可以看出來react總共有10個(gè)周期函數(shù)(render重復(fù)一次),這個(gè)10個(gè)函數(shù)可以滿足我們所有對(duì)組件操作的需求苏携,利用的好可以提高開發(fā)效率和組件性能订框。
轉(zhuǎn)自鏈接:https://blog.csdn.net/chern1992/article/details/78431837