Reactjs 踏坑指南1: 一些概念
Reactjs 踏坑指南1: 知識點
- 什么是React
- 虛擬DOM
- JSX
- 組件
- 生命周期和狀態(tài)
- 事件
- 單項數(shù)據(jù)流
- Reactjs和Angularjs的對比
React簡介
React是一個Facebook開發(fā)的UI庫。使用這個庫可以很方便的開發(fā)交互式的、具有表達力的和可重用的UI組件。本身并不是一個框架,可視為是視圖層,并且是一個以組件為基礎(chǔ)的高效視圖。對于React應(yīng)用而言,你需要分割你的頁面,使其成為一個個的組件。也就是說你的應(yīng)用是由一個個組件構(gòu)成的。這種分割、復(fù)用組件的方式開發(fā)頁面,我們稱之為組件驅(qū)動開發(fā)。
這個庫還使用了一種叫做虛擬DOM(Virtual DOM)的概念,這些DOM可以根據(jù)狀態(tài)有選擇的渲染。這樣,頁面就會盡量的減少DOM操作而達到保持頁面狀態(tài)的效果。
- React JSFiddle 在線編輯工具
- React 入門示例
虛擬DOM
用于優(yōu)化視圖的渲染和刷新。以前我們更新視圖時,需要先清空DOM容器中的內(nèi)容,然后將最新的DOM和數(shù)據(jù)追加到容器中,現(xiàn)在React將這一操作放到了內(nèi)存中。
詳細(xì)說明一下:
虛擬 DOM 是在 DOM 的基礎(chǔ)上建立了一個抽象層,我們對數(shù)據(jù)和狀態(tài)所做的任何改動,都會被自動且高效的同步到虛擬 DOM,最后再批量同步到 DOM 中。
React 會在內(nèi)存中維護一個虛擬 DOM 樹,當(dāng)我們對這個樹進行讀或?qū)懙臅r候,實際上是對虛擬 DOM 進行的。當(dāng)數(shù)據(jù)變化時,然后 React 會自動更新虛擬 DOM,然后拿新的虛擬 DOM 和舊的虛擬 DOM 進行對比,找到有變更的部分,得出一個Patch,然后將這個 Patch 放到一個隊列里,最終批量更新這些 Patch 到 DOM 中。
這樣的機制可以保證即便是根節(jié)點數(shù)據(jù)的變化,最終表現(xiàn)在 DOM 上的修改也只是受這個數(shù)據(jù)影響的部分,可以保證非常高效的渲染。
- 關(guān)于虛擬DOM diff算法的詳細(xì)分析
因為React使用了虛擬DOM,因此借助這種方式使得在服務(wù)端渲染輸出HTML成為可能。
JSX
JSX在ECMAScript的基礎(chǔ)上提供了類似于XML的擴展。
- JSX in depth
組件
使用ReactDOM的render方法的時候,第一個參數(shù)是需要渲染的我們創(chuàng)建的組件,第二個是HTML的DOM節(jié)點,組件渲染之后在這里添加。我們可以使用createClass方法創(chuàng)建組件。
var MyComponent = React.createClass({render: function(){return (<h1>Hello, world!</h1>);} }); 復(fù)制代碼注意:
- 類名一定要首字母大寫
- 添加組件屬性時,如果要使用class屬性和for屬性,屬性名不能直接用class和for,因為他們兩個是javascript的關(guān)鍵字,用className和htmlFor代替
組件創(chuàng)建好之后就可以在文檔里渲染出來了:
ReactDOM.render(<MyComponent />,document.getElementById('mount-point') ); 復(fù)制代碼創(chuàng)建組件的時候,可以給組件添加一些屬性,這些屬性都存在于props中。這些屬性可以通過this.props在組件內(nèi)訪問,也可以在render方法渲染時使用。
var MyComponent = React.createClass({render: function(){return (<h1>Hello, {this.props.name}!</h1>);} });ReactDOM.render(<MyComponent name="handsome" />,document.getElementById('mount-point') ); 復(fù)制代碼生命周期和狀態(tài)
生命周期
- componentWillMount 在渲染之前調(diào)用一次。
- componentDidMount 在渲染之后調(diào)用一次。
- shouldComponentUpdate 返回值決定組件是否需要update。
- componentWillUnmount 在卸載組件之前調(diào)用。
狀態(tài)
- getInitialState 返回State的初始值。
- getDefaultProps 獲取props的初始值。
- mixins 一組對象,主要用來擴展當(dāng)前組件的功能。
每一個組件都包含一個state對象和一個props對象。State(狀態(tài))用setState方法設(shè)置。調(diào)用setState方法會觸發(fā)UI的更新,也是實現(xiàn)交互式開發(fā)的必要基礎(chǔ)。如果我們要在一開始設(shè)定初始狀態(tài)(initial state),可以調(diào)用getInitialState方法。
state用來在創(chuàng)建組件的時候設(shè)置屬性,props用于渲染的時候生成想組件綁定屬性?
var MyComponent = React.createClass({getInitialState:function(){return {count: 5};},render: function(){return (<h1>Hello, {this.state.count}!</h1>);} }); 復(fù)制代碼事件
作為屬性包含在組件中
var Counter = React.createClass({incrementCount: function(){this.setState({count: this.state.count + 1});},getInitialState: function(){return {count: 0}},render: function(){return (<div class="my-component"><h1>Count: {this.state.count}</h1><button type="button" onClick={this.incrementCount}>Increment</button></div>);} });ReactDOM.render(<Counter />,document.getElementById('mount-point') ); 復(fù)制代碼單向數(shù)據(jù)流
在jquery時代,我們都是基于事件驅(qū)動,對于簡單的交互需求而言,這確實足夠了,而且開發(fā)起來非常迅速。但業(yè)務(wù)一旦復(fù)雜,這種基于事件驅(qū)動的東西就會變得很亂,頁面需要更新的DOM很多,就容易出錯。
單向數(shù)據(jù)流的概念就出現(xiàn)了。更新 DOM 的數(shù)據(jù)總是從頂層流下來,用戶事件不直接操作 DOM,而是操作頂層數(shù)據(jù)。這些數(shù)據(jù)從頂層流下來同時更新了DOM。你的代碼就很少會直接處理DOM,而是只處理數(shù)據(jù)的變更。這樣會很大程度上簡化代碼和邏輯。
舉個例子:我點擊一個button,然后頁面上一個span里數(shù)字+1,原有的思考邏輯是“點擊發(fā)生,然后數(shù)據(jù)變化,然后UI跟著變化+1”。而現(xiàn)在的思考邏輯是我的數(shù)據(jù)變化了,那么我的UI會自動更新,那么我只用考慮“點擊發(fā)生,數(shù)據(jù)變化”。甚至可以把UI和數(shù)據(jù)變化分層然后處理。
具體地說:
在一個多組件結(jié)構(gòu)里,一個父組件需要負(fù)責(zé)管理狀態(tài),并把數(shù)據(jù)通過props向下發(fā)放。
組件的狀態(tài)通過setState方法更新。數(shù)據(jù)通過設(shè)置子組件的屬性來傳遞給子組件,子組件通過this.props來獲取這些數(shù)據(jù)
例子1: 實現(xiàn)一個動態(tài)查找框
var FilteredList = React.createClass({filterList: function(event){var updatedList = this.state.initialItems;updatedList = updatedList.filter(function(item){return item.toLowerCase().search(event.target.value.toLowerCase()) !== -1;});this.setState({items: updatedList});},getInitialState: function(){return {initialItems: ["Apples","Broccoli","Chicken","Duck","Eggs","Fish","Granola","Hash Browns"],items: []}},componentWillMount: function(){this.setState({items: this.state.initialItems})},render: function(){return (<div className="filter-list"><input type="text" placeholder="Search" onChange={this.filterList}/><List items={this.state.items}/></div>);} });var List = React.createClass({render: function(){return (<ul>{this.props.items.map(function(item) {return <li key={item}>{item}</li>})}</ul>) } });ReactDOM.render(<FilteredList/>, document.getElementById('mount-point')); 復(fù)制代碼React和Angular的對比
Angular是框架,React是類庫。ng是一個完整的框架,提供了比 React 多得多的建議和功能,你只需要直接使用就可以了。而要用React,開發(fā)者通常還需要借助別的類庫來打造一個真正的應(yīng)用。比如你可能需要react-router庫來處理路由、redux或flux管理state、額外的庫做測試以及管理依賴等等。 "如果僅從框架這一點來看,選擇Angular還是React就像選擇直接購買成品電腦還是買零件自己組裝一樣。"
在大小方面,由于ng是一個大而全的框架,自帶了更多的功能。而React只加載你需要的部件,react要比ng小得多。很多應(yīng)用其實用不到這種大型框架提供的所有功能。在這個越來越擁抱微服務(wù)、微應(yīng)用、單一職責(zé)模塊(single-responsibility packages)的時代,React 通過讓你自己挑選必要模塊,讓你的應(yīng)用大小真正做到量身定做。
React以JavaScript為中心,把"HTML"放到JS里,JavaScript遠(yuǎn)比HTML要強大。因此,增強JavaScript讓其支持標(biāo)簽要比增強HTML讓其支持邏輯要合理得多。無論如何,HTML與JavaScript 都需要某種方式以粘合在一起。 Angular是以HTML而非JavaScrip為中心的,把“JS”放到HTML里。你必須學(xué)習(xí)學(xué)一大堆Angular特有的語法(標(biāo)簽),即ng框架特有的HTML補丁(shim),比如為HTML加入了循環(huán)語義的HTML特性。而React只需要你懂JS。
總結(jié)
以上是生活随笔為你收集整理的Reactjs 踏坑指南1: 一些概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LindDotNetCore~职责链模式
- 下一篇: haproxy+keepalived实现