react redux学习之路
React 自學(xué)
chapter one React新的前端思維方式
React的首要思想是通過組件(Component)來開發(fā)應(yīng)用。所謂組件,簡單說,指的是能夠完成某個(gè)特定功能的獨(dú)立的、可重用的代碼。
基于組件的應(yīng)用開發(fā)是廣泛使用的軟件開發(fā)模式,用分而治之的方法,把一個(gè)大的應(yīng)用分解成若干的小組件,每個(gè)組件只關(guān)注某個(gè)小范圍的特定功能,但是把組件組合起來,就能構(gòu)成一個(gè)功能龐大的應(yīng)用。如果分解功能的過程足夠巧妙,那么每個(gè)組件可以在不同場景下重用,那樣不光可以構(gòu)建龐大的應(yīng)用,還可以構(gòu)建出靈活的應(yīng)用。打個(gè)比方,每個(gè)組件是一塊磚,而一個(gè)應(yīng)用是一座樓,想要一次鍛造就構(gòu)建一座樓是不現(xiàn)實(shí)的。實(shí)際上,總是先鍛造很多磚,通過排列組合這些磚,才能構(gòu)建偉大的建筑。
React非常適合構(gòu)建用戶交互組件。
jsx 是進(jìn)步還是退步?
多年來,業(yè)界一直流行三次分離,即html(結(jié)構(gòu))、css(表現(xiàn))、js(邏輯)分離,一般會寫在不同的文件之中。
而jsx把類似HTML的標(biāo)記語言和javascript混在一起了,但是,隨著時(shí)間的推移,業(yè)界分離的認(rèn)識有了改變,將html,css,js這三種語言分在三種不同的文件里面,實(shí)際上是把不同技術(shù)分開管理了,而不是邏輯上的“分而治之”。
html之中的onclick與jsx之中的onClick的區(qū)別:
- onclick添加的時(shí)間處理函數(shù)是在全局環(huán)境下執(zhí)行的,這污染了全局環(huán)境,很容易產(chǎn)生意料不到的后果;
- 給很多DOM袁術(shù)添加onclick時(shí)間,可能會影響網(wǎng)頁的性能,畢竟,網(wǎng)頁需要的時(shí)間處理函數(shù)越多,性能就會越低;
- 對于使用onclick的DOM元素,如果要動態(tài)地從DOM樹中刪除的話,需要把對應(yīng)的時(shí)間處理器注銷,加入忘了注銷,就可能造成內(nèi)存泄露,這樣的bug,很難被發(fā)現(xiàn)。
在jsx之中,onClick掛載的每個(gè)函數(shù),都可以控制在組件范圍內(nèi),不會污染全局空間。
我們在jsx中看到了一個(gè)組件使用了onClick,但并沒有產(chǎn)生直接使用onclick的html,而是使用了事件委托(event delegation)的方式處理點(diǎn)擊事件,無論有多少個(gè)onClick出現(xiàn),其實(shí)最后都只在DOM樹上添加了一個(gè)事件處理函數(shù),掛載在最頂層的DOM節(jié)點(diǎn)上。所有的點(diǎn)擊事件都被這個(gè)事件處理函數(shù)捕獲,然后根據(jù)具體組件分配給特定函數(shù),使用事件委托的性能當(dāng)然比每個(gè)onClick都掛載一個(gè)事件處理函數(shù)要高。
因?yàn)镽eact控制了組件的生命周期,我們還可以在React組件中定義樣式。
分解Reac應(yīng)用
React的理念,歸結(jié)為一個(gè)公式,就像下面這樣:
UI = render(data)用戶看到的界面(UI),應(yīng)該是一個(gè)函數(shù)render執(zhí)行結(jié)果,只接受數(shù)據(jù)(data)作為參數(shù)。這個(gè)函數(shù)是一個(gè)純函數(shù),所謂純函數(shù),指的的是沒有任何副作用,輸出完全依賴于輸入的函數(shù),兩次函數(shù)調(diào)用如果輸入相同,得到的結(jié)果也絕對相同。如此一來,最終的用戶界面,在render函數(shù)確定的情況下完全取決于輸入數(shù)據(jù)。
對于開發(fā)者來說,重要的是區(qū)分開那些是屬于data,哪些屬于render,想要更新用戶界面,要做的就是更新data,用戶界面自然會做出相應(yīng),所以react實(shí)際的也是“響應(yīng)式編程”(reactive programming)的思想,這也就是react為什么叫做react的原因。
Virtual Dom
既然react應(yīng)用就是通過重復(fù)渲染來實(shí)現(xiàn)用戶交互,你可能會有一個(gè)疑惑:這樣的重復(fù)渲染會不會效率太低了呢?在jQuery的實(shí)現(xiàn)方式中,我們可以清楚地看到每次只有需要變化的哪一個(gè)DOM元素被修改了;可是,在react的實(shí)現(xiàn)方式中,看起來每次render函數(shù)被調(diào)用,都需要把整個(gè)組件重新繪制一次,這樣看起來有點(diǎn)浪費(fèi)。
事實(shí)并不是這樣,react利用virtual dom,讓每次渲染都只重新渲染最少的DOM元素。要了解virtual dom,就要先了解dom,dom是結(jié)構(gòu)話文本的抽象表達(dá)式,特定于web環(huán)境中,這個(gè)結(jié)構(gòu)化文本就是html文本,html中的每個(gè)元素都對應(yīng)dom中某個(gè)節(jié)點(diǎn),這樣,因?yàn)閔tml元素的逐級包含關(guān)系,dom節(jié)點(diǎn)自然就構(gòu)成了一個(gè)樹形結(jié)構(gòu),成為DOM樹。
瀏覽器為了渲染html格式的網(wǎng)頁,會先將html文本解析以構(gòu)建dom樹,然后根據(jù)dom樹渲染出用戶看到的界面,當(dāng)要改變界面內(nèi)容的時(shí)候,就去改變dom樹上的節(jié)點(diǎn)。
web前端開發(fā)關(guān)于性能優(yōu)化有一個(gè)原則:盡量減少DOM操作。雖然dom操作也只式一些簡單的javascript語句,但是dom操作會引起瀏覽器對網(wǎng)頁進(jìn)行重新布局,重新繪制,這就是一個(gè)比javascript語句執(zhí)行慢很多的過程。
如果使用mustache或者h(yuǎn)ogan這樣的模板工具,那就是生成html字符串賽到網(wǎng)頁中,瀏覽器又要做一次解析生產(chǎn)新的DOM節(jié)點(diǎn),然后替換DOM樹上對應(yīng)的子樹部分,這個(gè)過程的肯定效率不高。雖然jsx看起來很像是一個(gè)模板,但是最終會被babel解析為一條條創(chuàng)建react組件或者h(yuǎn)tml元素的語句,神奇之處在于,react并不是通過這些語句直接構(gòu)建DOM樹,而是首先構(gòu)建virtual dom。
既然dom樹是對html的抽象,那virtual dom就是對dom樹的抽象。virtual dom不會觸及瀏覽器部分,只是存在于javascript空間的樹形結(jié)構(gòu),每次自上而下渲染react組件時(shí),會對比這一次產(chǎn)生的virtual dom和上一次渲染的virtual dom,對比就會發(fā)現(xiàn)差別,然后修改真正的dom樹時(shí)就只需要初級差別中的部分就行。
jquery的方式直觀易懂,對于初學(xué)者十分適用,但是當(dāng)項(xiàng)目逐漸變得龐大時(shí),用jquery寫出的代碼往往互相糾纏,不同的事件直接修改dom元素。
使用react的方式,就可以避免構(gòu)建這樣復(fù)雜的程序結(jié)構(gòu),無論何種事件,引發(fā)的都是react組件的重新渲染,至于如何只修改必要的dom部分,則完全交給react去操作,開發(fā)者并不需要關(guān)系。react利用函數(shù)式編程的思維來解決用戶界面渲染的問題,最大的優(yōu)勢式開發(fā)者的效率會大大提高,開發(fā)出來的代碼可維護(hù)性和可閱讀性也大大增強(qiáng)。
chapter two 設(shè)計(jì)高質(zhì)量的react組件
作為一個(gè)合格的開發(fā)者,不要只滿足于編寫出了可以運(yùn)行的代碼,而要了解代碼背后的工作原理;不要只滿足于自己編寫的程序能夠運(yùn)行,還要讓自己的代碼可讀而且易于維護(hù)。這樣才能開發(fā)出高質(zhì)量的軟件。
作為軟件設(shè)計(jì)的通則,組件的劃分要滿足高內(nèi)聚(high cohesion)和低耦合(low coupling)的原則。
高內(nèi)聚指的式把邏輯緊密的相關(guān)內(nèi)容放在一個(gè)組件中。用戶界面無外乎內(nèi)容、交互行為和樣式。傳統(tǒng)上,內(nèi)容由html表示,交互行為放在javascript代碼文件中,樣式放css文件中定義。這雖然滿足一個(gè)功能模塊的需要,卻要放在三個(gè)不同的文件中,這其實(shí)不滿足高內(nèi)聚的原則。react卻不是這樣,展示內(nèi)容的jsx、定義行為的javascript代碼,甚至定義樣式的css,都可以放在一個(gè)javascript文件中,因?yàn)樗麄儽緛砭褪菫榱藢?shí)現(xiàn)一個(gè)具體的目的而存在的,所以說react天生具有高內(nèi)聚的特點(diǎn)。
低耦合指的式不同組件之間的依賴關(guān)系要盡量弱化,也就是每個(gè)組件要盡量獨(dú)立。保持整個(gè)系統(tǒng)的低耦合度,需要對系統(tǒng)中的功能有充分的認(rèn)識,然后根據(jù)功能點(diǎn)劃分模塊,讓不同的組件去實(shí)現(xiàn)不同的功能,這個(gè)功夫還在開發(fā)者身上,不過,react組件的對外接口非常規(guī)范,方便開發(fā)者設(shè)計(jì)低耦合的系統(tǒng)。
react組件的數(shù)據(jù)
"差勁的程序要操心代碼,優(yōu)秀的程序要操心數(shù)據(jù)結(jié)構(gòu)和他們之間的關(guān)系。"
react組件的數(shù)據(jù)分為兩種,prop和state,無論prop或者state的改變,都可能引發(fā)組件的重新渲染,那么,設(shè)計(jì)一個(gè)組件的時(shí)候嗎,什么時(shí)候選擇prop什么時(shí)候選擇用state呢?原則很簡單,prop是組件對外的接口,state是組件內(nèi)部的狀態(tài),對外用prop,內(nèi)部用state。
每個(gè)react組件都是獨(dú)立存在的模塊,組件之外的一切都是外部世界,外部世界就是通過prop來和組件對話的。
當(dāng)prop的類型不是字符串類型時(shí),在jsx中必須使用花括號{}把prop值包住,所以style的值有兩層花括號,外層花括號代表是jsx的語法,內(nèi)層的花括號代表這是一個(gè)對象常量。
react中的prop
prop 傳值分析:
class Counter extends Component {constructor(props){super(props);this.onClickIncrementButton = this.onClickIncrementButton.bind(this);this.onClickDecrementButton = this.onClickDecrementButton.bind(this);this.state = {count:props.initValue || 0;}} }如果一個(gè)組件需要定義自己的構(gòu)造函數(shù),一定要記得在構(gòu)造函數(shù)的第一行通過super調(diào)用父類也就是React.Component的構(gòu)造函數(shù)。如果在構(gòu)造函數(shù)中沒有調(diào)用super(props),那么組件實(shí)例被構(gòu)造之后,類實(shí)例的所有成員函數(shù)就無法通過this.props訪問到父組件傳遞過來的props值。很明顯,給this.props賦值是React.Component構(gòu)造函數(shù)的工作之一。
在Counter的構(gòu)造函數(shù)中還給哦i昂貴成員綁定了當(dāng)前this的執(zhí)行環(huán)境,因?yàn)閑s6方法構(gòu)造的react組件類并不自動給我們綁定this到當(dāng)前實(shí)例對象。在構(gòu)造函數(shù)的最后,我們可以看到讀取傳入prop的方法,在構(gòu)造函數(shù)中可以通過參數(shù)props獲得傳入prop值,在其他函數(shù)中則可以通過this,props訪問傳入的prop的值,比如在counter組件的render函數(shù)中,我們就是通過this.props獲得傳入的caption ,render函數(shù)代碼如下:
render(){const { caption } = this.props;return <div><button style={buttonStyle} onClick={this.onClickIncrementButton}>+</button><button style={buttonStyle} onClick={this.onClickDecremnetButton}>-</button><span>{caption} count:{ this.state.count } </span></div> }react的state
驅(qū)動組件渲染過程的除了prop,還有state,state代表組件的內(nèi)部狀態(tài)。由于react組件不能修改傳入的prop,所以需要i記錄自身數(shù)據(jù)變化,就要使用state。
通常在組件類的構(gòu)造函數(shù)結(jié)尾出初始化state,在counter構(gòu)造函數(shù)中,通過this.state的賦值完成了對組件state的初始化。代碼如下:
于2017.10.2
differences between react element and react component
react elements are plain objects.They describe what you want to see on the screen.React elements are inmutable .Once you create an element,you can't change its children or attributes.An element is like a single frame in a movie :it represents the UI at a certain point in time.
react components are like Javacript functions.they accept arbitrary inputs (called "props") and return react elements describing what should appear on the screen.
functional and class components
React componets must act like pure functions with repect to their props.
Locak state is exactly that:a feature available only to a Class.
什么是組件
能夠完成某個(gè)特定功能的獨(dú)立可重用的代碼。基于組件是廣泛使用的軟件開發(fā)模式,是分而治之的方法。把大的應(yīng)用分解成為若干個(gè)小的組件,每個(gè)組件專注某個(gè)特定的功能。把組件合起來就能夠成為一個(gè)功能龐大的應(yīng)用。如果組件功能分解足夠巧妙,每個(gè)組件可以在不同的場景下重用,可以構(gòu)建出龐大靈活的應(yīng)用。
prop
當(dāng)外部世界傳遞一些數(shù)據(jù)給React組件,一個(gè)最直接的方式就是通過prop;同樣React組件要反饋數(shù)據(jù)給外部數(shù)據(jù),也可以用prop,因?yàn)镻rop的類型限于純數(shù)據(jù),也可以是函數(shù),函數(shù)類型的prop等于讓父組件交給子組件一個(gè)毀掉函數(shù),子組件在恰當(dāng)?shù)膶?shí)際調(diào)用函數(shù)的類型prop,可以帶上必要的參數(shù),這樣就可以反過來把信息傳遞給外部的世界。
哈哈:看到這里,不禁想到了一個(gè)例子,一個(gè)也是在別處調(diào)用的情況,就是常見的跨域方式,如jsonp,script標(biāo)簽請求的數(shù)據(jù)就返回就是回掉一個(gè)之前已經(jīng)定義好的函數(shù)。對于后端的數(shù)據(jù)處理來說,是相當(dāng)于一個(gè)黑匣子。對于父子組件而言,也相當(dāng)一個(gè)黑匣子里面調(diào)用數(shù)據(jù)。兩個(gè)例子都是一個(gè)回掉函數(shù)的作怪。常言到,函數(shù)是代碼的分割,此話可當(dāng)真。
轉(zhuǎn)載于:https://www.cnblogs.com/lakeInHeart/p/7537824.html
總結(jié)
以上是生活随笔為你收集整理的react redux学习之路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lsof 命令简介
- 下一篇: linux下修改rm命令防止误删除