React基礎(Diff算法,屬性和狀態)

1.React的背景原理javascript

  (1)React Diff算法流程css

  

  (2)React虛擬DOM機制html

  React引入了虛擬DOM(Virtual DOM)的機制:在瀏覽器端用Javascript實現了一套DOM API。java

  基於React進行開發時全部的DOM構造都是經過虛擬DOM進行,每當數據變化時,React都會從新構建整個DOM樹,而後React將當前整個DOM樹和上一次的DOM樹進行對比,獲得DOM結構的區別,而後僅僅將須要變化的部分進行實際的瀏覽器DOM更新react

  並且React可以批處理虛擬DOM的刷新,在一個事件循環(Event Loop)內的兩次數據變化會被合併,例如你連續的先將節點內容從A變成B,而後又從B變成A,React會認爲UI不發生任何變化,而若是經過手動控制,這種邏輯一般是極其複雜的。jquery

  儘管每一次都須要構造完整的虛擬DOM樹,可是由於虛擬DOM是內存數據,性能是極高的而對實際DOM進行操做的僅僅是Diff部分,於是能達到提升性能的目的。這樣,在保證性能的同時,開發者將再也不須要關注某個數據的變化如何更新到一個或多個具體的DOM元素,而只須要關心在任意一個數據狀態下,整個界面是如何Render的。web

總之一句話:根據 React 的設計,全部的 DOM 變更,都先在虛擬 DOM 上發生,而後再將實際發生變更的部分,反映在真實 DOM上算法

2.屬性和狀態瀏覽器

 React 的一大創新,就是將組件當作是一個狀態機,一開始有一個初始狀態,而後用戶互動,致使狀態變化,從而觸發從新渲染 UI 服務器

 React裏面的React.render方法:

 React.render 是 React 的最基本方法,用於將模板轉爲 HTML 語言,並插入指定的 DOM 節點。

 下面的例子就是把<h1>標題插入到container節點中

  

  這裏須要注意的是,react並不依賴jQuery,固然咱們可使用jQuery,可是render裏面第二個參數必須使用JavaScript原生的getElementByID方法,不能使用jQuery來選取DOM節點。

  (1)狀態:

  狀態是和組件本身相關的,既不和父組件相關,也不和子組件相關,
  組件不能修改本身的屬性,但能夠從父組件獲取屬性,父組件也能夠修改屬性,也能夠修改子組件的屬性。
  組件嵌套實質就是父子關係
  

  (2)狀態的用法:

  》getInitialState(函數):初始化每一個實例特有的狀態。它只是在實例建立的時候被調用,建立完畢以後不會再被調用

  》setState(函數):更新組件的狀態。

  

$(document).ready(function(){
	var InputState=React.createClass({
		getInitialState:function(){
			return {enable:false};
		},
		handleClick:function(){
			this.setState({enable:!this.state.enable});
		},
		render:function(){
			return (
				<p>
					<input type="text" disabled={this.state.enable}/>
					<button onClick={this.handleClick}>Change State</button>
				</p>
				);			
		}
	});
	ReactDOM.render(<InputState/>,document.getElementById('container'));

});

  這裏,咱們又使用到了一個方法getInitialState,這個函數在組件初始化的時候執行必須返回NULL或者一個對象。這裏咱們能夠經過this.state.屬性名來訪問屬性值,這裏咱們將enable這個值跟input的disabled綁定,當要修改這個屬性值時,要使用setState方法。咱們聲明handleClick方法,來綁定到button上面,實現改變state.enable的值。

  原理分析:

  上面代碼是一個InputState 組件,它的 getInitialState 方法用於定義初始狀態,也就是一個對象,這個對象能夠經過 this.state 屬性讀取。當用戶點擊組件,致使狀態變化,this.setState 方法就修改狀態值,每次修改之後,自動調用 this.render 方法,再次渲染組件。

  這裏值得注意的幾點以下:

  1)getInitialState函數必須有返回值,能夠是NULL或者一個對象。

  2)訪問state的方法是this.state.屬性名。

  3)變量用{}包裹,不須要再加雙引號。如:{this.props.name}

  (3)屬性:

  組件的屬性能夠接受任意值,字符串、對象、函數等等均可以

  React 容許將代碼封裝成組件(component),而後像插入普通 HTML 標籤同樣,在網頁中插入這個組件React.createClass 方法就用於生成一個組件類。

<!DOCTYPE html>
<html lang="zh-cn">
<head>
	<meta charset="UTF-8">
	<title>屬性</title>
	<script src="./build/react.js"></script>
	<script src="./build/react-dom.js"></script>
	<script src="./build/browser.min.js"></script>
	<script src="./build/jquery.min.js"></script>
	
</head>
<body>
	<div id="container"></div>
</body>
	<script type="text/babel" >
		$(document).ready(function(){
	var Greet=React. createClass({
	render:function(){
		return <h1>Hello {this.props.name}</h1>;
	}
});
ReactDOM.render(<Greet name="Jack"/>,
	document.getElementById('container')
	);
});

  注意:

  首先,最後一個 <script> 標籤的 type 屬性爲 text/babel 。這是由於 React 獨有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" 。

  其次,上面代碼一共用了三個庫: react.js 、react-dom.js 和 Browser.js ,它們必須首先加載。其中,react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,Browser.js 的做用是將 JSX 語法轉爲 JavaScript 語法,這一步很消耗時間,實際上線的時候,應該將它放到服務器完成。

  關於屬性幾個注意的地方:

  1)獲取屬性的值用的是this.props.屬性名

  2)建立的組件名稱首字母必須大寫。如:var Greet=React. createClass({});

  3)爲元素添加css的class時要用className

  4)組件的style屬性的設置方式也值得注意,要寫成style={{width: this.state.witdh}}。第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象。

3.屬性和狀態的區別

  因爲 this.props 和 this.state 都用於描述組件的特性,可能會產生混淆。

  一個簡單的區分方法是,this.props 表示那些一旦定義,就再也不改變的特性,而 this.state 是會隨着用戶互動而產生變化的特性。

  狀態是和組件本身相關的,既不和父組件相關,也不和子組件相關,
  組件不能修改本身的屬性,但能夠從父組件獲取屬性,父組件也能夠修改屬性,也能夠修改子組件的屬性。
   
  

  參考文檔:

  http://www.cocoachina.com/webapp/20150721/12692.html

  http://www.ruanyifeng.com/blog/2015/03/react.html

相關文章
相關標籤/搜索