一、React的簡介
React 起源於 Facebook 的內部項目,因爲該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,在2013年5月開源了。
二、React的解讀
1.React不是一個完整的MVC框架,最多可以認爲是MVC中的V(View),甚至React並不非常認可MVC開發模式;
2.React的服務器端Render能力只能算是一個錦上添花的功能,並不是其核心出發點,事實上React官方站點幾乎沒有提及其在服務器端的應用;
3.React不是一個新的模板語言,JSX只是一個表象,沒有JSX的React也能工作。
ReactJS的背景和原理
在Web開發中,我們總需要將變化的數據實時反應到UI上,這時就需要對DOM進行操作。而複雜或頻繁的DOM操作通常是性能瓶頸產生的原因(如何進行高性能的複雜DOM操作通常是衡量一個前端開發人員技能的重要指標)。React爲此引入了虛擬DOM(Virtual DOM)的機制:在瀏覽器端用Javascript實現了一套DOM API。基於React進行開發時所有的DOM構造都是通過虛擬DOM進行,每當數據變化時,React都會重新構建整個DOM樹,然後React將當前整個DOM樹和上一次的DOM樹進行對比,得到DOM結構的區別,然後僅僅將需要變化的部分進行實際的瀏覽器DOM更新。
如果你像在90年代那樣寫過服務器端Render的純Web頁面那麼應該知道,服務器端所要做的就是根據數據Render出HTML送到瀏覽器端。如果這時因爲用戶的一個點擊需要改變某個狀態文字,那麼也是通過刷新整個頁面來完成的。服務器端並不需要知道是哪一小段HTML發生了變化,而只需要根據數據刷新整個頁面。換句話說,任何UI的變化都是通過整體刷新來完成的。而React將這種開發模式以高性能的方式帶到了前端,每做一點界面的更新,你都可以認爲刷新了整個頁面。
組件化
如果說MVC的思想讓你做到視圖-數據-控制器的分離,那麼組件化的思考方式則是帶來了UI功能模塊之間的分離。我們通過一個典型的Blog評論界面來看MVC和組件化開發思路的區別。
對於MVC開發模式來說,開發者將三者定義成不同的類,實現了表現,數據,控制的分離。開發者更多的是從技術的角度來對UI進行拆分,實現鬆耦合。
React認爲一個組件應該具有如下特徵:
(1)可組合(Composeable):一個組件易於和其它組件一起使用,或者嵌套在另一個組件內部。如果一個組件內部創建了另一個組件,那麼說父組件擁有(own)它創建的子組件,通過這個特性,一個複雜的UI可以拆分成多個簡單的UI組件;
(2)可重用(Reusable):每個組件都是具有獨立功能的,它可以被使用在多個UI場景;
(3)可維護(Maintainable):每個小的組件僅僅包含自身的邏輯,更容易被理解和維護;
三、編寫ReactJS簡單實例
直接上代碼吧:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<div id="example"></div>
<script type="text/babel">
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
tick();
// setInterval(tick);
// setInterval(tick, 1000);刷新該方法,每隔 1 秒, 就會通過 setInterval() 回調 ReactDOM.render() 方法來重新渲染元素
</script>
</body>
</html>
React.render 是 React 的最基本方法,用於將模板轉爲 HTML 語言,並插入指定的 DOM 節點。這裏需要注意的是,react並不依賴jQuery,當然我們可以使用jQuery,但是render裏面第二個參數必須使用JavaScript原生的getElementByID方法,不能使用jQuery來選取DOM節點。
四、jsx語法
HTML 語言直接寫在 JavaScript 語言之中,不加任何引號,這就是 JSX 的語法,它允許 HTML 與 JavaScript 的混寫,瞭解過AngularJs的看到下面的代碼一定會感覺很熟悉的,我們來看代碼:
var arr = [
<h1>你好</h1>,
<h2>夢想!</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
五、ReactJS組件
1、組件屬性
前面說了,ReactJS是基於組件化的開發,下面我們開始來學習ReactJS裏面的組件,React 允許將代碼封裝成組件(component),然後像插入普通 HTML 標籤一樣,在網頁中插入這個組件。React.createClass 方法就用於生成一個組件類。
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
ReactDOM.render(
<HelloMessage name="Runoob" />,
document.getElementById('example')
);
看到這段代碼,接觸過AngularJS的朋友們是不是有一種熟悉的感覺,不過這裏有幾點需要注意:
1)獲取屬性的值用的是this.props.屬性名
2)創建的組件名稱首字母必須大寫。
3)爲元素添加css的class時,要用className。
4)組件的style屬性的設置方式也值得注意,要寫成style={{width: this.state.witdh}}。
2、組件狀態
組件免不了要與用戶互動,React 的一大創新,就是將組件看成是一個狀態機,一開始有一個初始狀態,然後用戶互動,導致狀態變化,從而觸發重新渲染 UI 。下面我們來編寫一個小例子,一個文本框和一個button,通過點擊button可以改變文本框的編輯狀態,禁止編輯和允許編輯。通過這個例子來理解ReactJS的狀態機制。先看代碼:
這裏,我們又使用到了一個方法getInitialState,這個函數在組件初始化的時候執行,必需返回NULL或者一個對象。這裏我們可以通過this.state.屬性名來訪問屬性值,這裏我們將enable這個值跟input的disabled綁定,當要修改這個屬性值時,要使用setState方法。我們聲明handleClick方法,來綁定到button上面,實現改變state.enable的值。效果如下:
原理分析:
當用戶點擊組件,導致狀態變化,this.setState 方法就修改狀態值,每次修改以後,自動調用 this.render 方法,再次渲染組件。
這裏值得注意的幾點如下:
1)getInitialState函數必須有返回值,可以是NULL或者一個對象。
2)訪問state的方法是this.state.屬性名。
3)變量用{}包裹,不需要再加雙引號。
3、組件的生命週期
組件的生命週期分成三個狀態:
Mounting:已插入真實 DOM
Updating:正在被重新渲染
Unmounting:已移出真實 DOM
React 爲每個狀態都提供了兩種處理函數,will 函數在進入狀態之前調用,did 函數在進入狀態之後調用,三種狀態共計五種處理函數。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
此外,React 還提供兩種特殊狀態的處理函數。
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
tick();
// setInterval(tick);
// setInterval(tick, 1000);刷新該方法,每隔 1 秒, 就會通過 setInterval() 回調 ReactDOM.render() 方法來重新渲染元素
4、組件的嵌套
React是基於組件化的開發,那麼組件化開發最大的優點是什麼?毫無疑問,當然是複用,下面我們來看看React中到底是如何實現組件的複用的
這裏我們創建了一個Search組件,然後又創建了一個Page組件,然後我們在Page組件中調用Search組件,並且調用了兩次,這裏我們通過屬性searchType傳入值。
六、ReactJS小結
關於ReactJS今天就先學習到這裏了,下面來總結一下,主要有以下幾點:
1、ReactJs是基於組件化的開發,所以最終你的頁面應該是由若干個小組件組成的大組件。
2、可以通過屬性,將值傳遞到組件內部,同理也可以通過屬性將內部的結果傳遞到父級組件(留給大家研究);要對某些值的變化做DOM操作的,要把這些值放到state中。
3、爲組件添加外部css樣式時,類名應該寫成className而不是class;添加內部樣式時,應該是style={{opacity: this.state.opacity}}而不是style=”opacity:{this.state.opacity};”。
4、組件名稱首字母必須大寫。
5、變量名用{}包裹,且不能加雙引號。