如今,前端框架Angular,React和Vue逐漸成熟起來(lái),他們?nèi)齻€(gè)各顯其色,下面我們就先來(lái)熟悉輕量級(jí)的React吧!!!
React
是什么 (What)
- React是一個(gè)JavaScript的UI庫(kù),簡(jiǎn)單來(lái)說(shuō)是MVC中的V
誰(shuí)提出的,提出的原因(Why & Who)
- React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿意,就決定自己寫(xiě)一套,用來(lái)架設(shè) Instagram的網(wǎng)站,在2013年開(kāi)源。
特點(diǎn)(How)
- 輕量級(jí)的一個(gè)庫(kù)
- 組件化
- 速度快
- 單向數(shù)據(jù)流
-
跨瀏覽器兼容(支持IE8)
know-react.png
簡(jiǎn)單的了解React背景后,接下來(lái)我們看看React的一些關(guān)鍵詞
React的關(guān)鍵詞
- 安裝
- JSX語(yǔ)法
- Rendering
- 組件、props、state
- 處理事件
- 生命周期
- 虛擬DOM
安裝
- 根據(jù)官網(wǎng)直接下載安裝包
- 使用包管理器(npm、yarn)安裝react
- npm init
- npm install react react-dom
或 - yarn init
- yarn add react react-dom
Hello world
安裝完之后,運(yùn)用React寫(xiě)個(gè)“Hello React”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello React</title>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello React</h1>,
document.getElementById('example')
);
</script>
</body>
</html>
運(yùn)行結(jié)果:
從代碼中可以看出想在html文件中運(yùn)行React,需要引入react.js、react-dom.js和browser.min.js這三個(gè)文件,瀏覽器器才能識(shí)別React,其次就是script標(biāo)簽的類型應(yīng)為text/babel,因?yàn)镽eact的JSX語(yǔ)法(下面會(huì)介紹到),與JavaScript不兼容。
上面這個(gè)Hello React簡(jiǎn)單例子,就是React最基本的HTML模板,至于為什么這樣寫(xiě),瀏覽器就會(huì)出現(xiàn)這樣的結(jié)果,不要著急,待我娓娓道來(lái)。
JSX語(yǔ)法
const element = <h1>Hello React</h1>;
上面這種寫(xiě)法既不是字符串賦值,也不是HTML標(biāo)簽。其被稱為JSX語(yǔ)法,是JS的一種擴(kuò)展。大部分情況下,在React中,我們用JSX來(lái)描述界面。JSX就像是一種模板語(yǔ)言,但它也包括JS的全部API。上面的HelloWrold例子中render
方法中第一個(gè)參數(shù)就是用JSX語(yǔ)法寫(xiě)的一個(gè)表達(dá)式。
Rendering element 渲染元素
ReactDOM.render(
<h1>Hello React</h1>,
document.getElementById('example')
);
渲染元素就是用最基本的ReactDOM.render()方法進(jìn)行渲染。就是將模板(<h1>Hello React</h1>
)轉(zhuǎn)換為HTML元素,插入到指定的DOM中去(插入到id
為example
元素中去)。
從圖片中可以看出,
<h1>Hello React</h1>
經(jīng)過(guò)編譯后,插入到id
為example
的div
中去。
組件、props、state
組件使得界面分離成獨(dú)立的,可重復(fù)使用的部件。概念上來(lái)講,組件就像是JavaScript函數(shù),他接收任意的輸入(被稱作props),且返回渲染頁(yè)面的元素。
定義組件的方法:JavaScript函數(shù)定義、ES6 Class定義
組件有兩個(gè)核心的概念:props和state
1.props
props是組件的屬性,由外部通過(guò)JSX屬性設(shè)置,一旦初始設(shè)置完成,就可以認(rèn)為props是不可修改的。關(guān)于props,官網(wǎng)有嚴(yán)格的規(guī)則:
All React components must act like pure functions with respect to their props.
所有的組件必須像純函數(shù)一樣對(duì)待他們的props。
什么是純函數(shù)呢?純函數(shù)就是相同的輸入總是返回相同的輸出的函數(shù)。這就意味著組件的props是不可修改的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello React</title>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
function Hello(props){
return <h1>Hello,{props.name}</h1>
}
ReactDOM.render(
<Hello name="React"/>,
document.getElementById('example')
);
</script>
</body>
</html>
運(yùn)行結(jié)果:
由此可以看出,運(yùn)行結(jié)果和上面例子的運(yùn)行結(jié)果一樣。這個(gè)例子是通過(guò)寫(xiě)JavaScript方法定義了一個(gè)組件,并且組件中添加了一個(gè)屬性
name
,值為React
。在Hello
組件中可以通過(guò)props.name
獲取name
屬性的值。上面提到React的props屬性是不可修改的,當(dāng)修改時(shí)則會(huì)報(bào)錯(cuò)。比如在Hello方法中進(jìn)行修改
function Hello(props){
props.name = "world";
return <h1>Hello,{props.name}</h1>
}
則瀏覽器就會(huì)報(bào)錯(cuò)
提示未知類型錯(cuò)誤:不能修改只讀對(duì)象屬性name的值
2.State
state 是組件的當(dāng)前狀態(tài),可以把組件簡(jiǎn)單看成一個(gè)“狀態(tài)機(jī)”,根據(jù)狀態(tài) state 呈現(xiàn)不同的 UI 展示。一旦狀態(tài)(數(shù)據(jù))更改,組件就會(huì)自動(dòng)調(diào)用 render 重新渲染 UI,這個(gè)更改的動(dòng)作會(huì)通過(guò) this.setState 方法來(lái)觸發(fā)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {liked: false};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({liked: !this.state.liked});
}
render() {
var text = this.state.liked ? "like" : "haven't liked";
return (
<p onClick={this.handleClick}>You {text} this.click to toggle</p>
)
}
}
ReactDOM.render(
<LikeButton></LikeButton>,
document.getElementById('example')
);
</script>
</body>
</html>
運(yùn)行結(jié)果:
再次點(diǎn)擊后
從代碼中看出初始化時(shí),
state.liked
值為false
,當(dāng)點(diǎn)擊<p>
標(biāo)簽里的文本時(shí),就會(huì)觸發(fā)click
事件,從而調(diào)用handleClick
方法,在該方法中通過(guò)setState
來(lái)修改state.liked
的值。
處理事件
React元素處理事件和DOM元素處理是類似的,但有兩點(diǎn)語(yǔ)法上的不同:
- React事件命名遵守駝峰命名規(guī)則,而不是小寫(xiě)命名
- 用JSX傳遞方法作為事件處理,而非字符串形式
生命周期
組件的生命周期分為三種狀態(tài):
- Mounting:已插入真實(shí) DOM
- Updating:正在被重新渲染
- Unmounting:已移出真實(shí) DOM
React 提供了五種處理函數(shù),will 函數(shù)在進(jìn)入狀態(tài)之前調(diào)用,did 函數(shù)在進(jìn)入狀態(tài)之后調(diào)用
- componentWillMount()
- componentDidMount()
- componentWillUpdate(object nextProps, object nextState)
- componentDidUpdate(object prevProps, object prevState)
- componentWillUnmount()
虛擬DOM
React頁(yè)面加載速度快,就是因?yàn)関irtual DOM(虛擬DOM)的存在,不直接操作原生DOM。React將DOM結(jié)構(gòu)存儲(chǔ)在內(nèi)存中,然后同render()的返回內(nèi)容進(jìn)行比較,計(jì)算出需要改動(dòng)的地方,最后才反映到DOM中當(dāng)局部DOM發(fā)生變化,頁(yè)面加載避免全部DOM的重新加載。