介紹
什么是React
React 是Facebook開發(fā)的UI庫,這個(gè)庫有助于創(chuàng)建交互式徒恋、基于狀態(tài)、可重用的UI部件亿乳。React已經(jīng)應(yīng)用與Facebook径筏,Instagram全部是用React寫的。
React 一個(gè)獨(dú)特的地方是桐款,它不僅可以運(yùn)用與客戶端夷恍,也可用于服務(wù)端酿雪,客戶端和服務(wù)端可一協(xié)同操作侄刽。
React 使用了叫做Virtual DOM概念的東西州丹,它可以根據(jù)狀態(tài)的變化,有選擇地渲染節(jié)點(diǎn)和子節(jié)點(diǎn)吓揪。為了更新部件所计,React做盡量少的DOM處理操作。
Virtual DOM如何工作叭首?
想象你以人為模型創(chuàng)建了對(duì)象。這個(gè)對(duì)象具有人的屬性矛物,實(shí)時(shí)反應(yīng)人當(dāng)前的狀態(tài)臀栈。這基本上就是React中DOM所做的赞警。
現(xiàn)在想象如果你使用這個(gè)對(duì)象并做了一些改變厢破。添加胡須,二頭肌笆焰,一雙英俊的眼睛见坑。在React世界里,當(dāng)你做這些改變的時(shí)候不皆,兩件事發(fā)生了霹娄。第一鲫骗,React運(yùn)行“辨別”算法,確定什么改變了枕磁。第二术吝,更新DOM排苍,確保結(jié)果和改變的一致。
React的工作方式凑队,不是根據(jù)真實(shí)的人從頭再建幔翰,它只改變對(duì)象的臉和胳膊遗增。這意味著,如果你在文本框中輸入文字霍狰,這時(shí)渲染操作開始,即使文本框的父節(jié)點(diǎn)沒有做更新的準(zhǔn)備康震,文本本身知道如何操作宾濒。
由于React使用的是虛擬的DOM绘梦,這也就產(chǎn)生了另一種有趣的可能。我們可以在服務(wù)端渲染虛擬的DOM钝诚,快速更新React視圖榄棵。
開始
使用React秉继,首先要安裝React CLI工具(用以創(chuàng)建React應(yīng)用)泽铛,運(yùn)行以下命令創(chuàng)建新應(yīng)用:
# 安裝 CLI 工具
npm install -g create-react-app
# 創(chuàng)建應(yīng)用
create-react-app my-app-name
# 安裝依賴包
cd my-app-name
npm install
頁面設(shè)置
設(shè)置頁面的時(shí)候盔腔,你需要引入react.js
和react-dom.js
及Babel編譯器腳本。然后在type
設(shè)置為text/babel
的腳本區(qū)域?qū)懖考╟omponent):
<!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/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<div id="myDiv"></div>
<script type="text/babel">
<!-- React Code Goes Here -->
</script>
</body>
</html>
React中弛随,部件(component)加載到元素(element)上瓢喉,所以在這個(gè)例子中,我們使用myDiv
作為它的父容器舀透。
雖然這個(gè)開始方式很容易栓票,在創(chuàng)建實(shí)際項(xiàng)目的時(shí)候,一般使用Browserify
或者Webpack
來將部件放置到不同的文件中愕够。
基礎(chǔ)
React是以部件為基礎(chǔ)的走贪,我們寫一個(gè):
<script type="text/jsx">
/** @jsx React.DOM */
React.render(
<h1>Hello, world!</h1>,
document.getElementById('myDiv')
);
</script>
如果這樣的代碼是你第一次看到,你會(huì)有點(diǎn)疑惑:這段代碼里隱含了Javascript/HTML的什么魔法惑芭?
JSX
它叫做JSX坠狡,是Javascript XML語法的變種,使你在腳本中寫類似HTML標(biāo)記逃沿。為了與Javascript保留關(guān)鍵字區(qū)別婴渡,對(duì)于一些常規(guī)的html標(biāo)記,在JSX中class
為className
凯亮,for
為htmlFor
边臼。如果不使用JSX,上述的代碼是這樣的:
/** @jsx React.DOM */
React.render(
React.DOM.h1(null, 'Hello, world!'),
document.getElementById('myDiv')
);
部件(components)
在上面代碼使用render
方法的時(shí)候假消,我們第一個(gè)參數(shù)是我們要渲染的部件硼瓣,第二個(gè)參數(shù)是部件要掛載的DOM節(jié)點(diǎn)。我們可以使用createClass
方法創(chuàng)建部件類置谦,在創(chuàng)建參數(shù)中對(duì)對(duì)象配置:
var MyComponent = React.createClass({
render: function(){
return (
<h1>Hello, world!</h1>
);
}
});
創(chuàng)建類之后堂鲤,我們可以在文檔中渲染它:
React.render(
<MyComponent/>,
document.getElementById('myDiv')
);
屬性(Props)
定義我們的部件時(shí),我們可以為部件定義屬性媒峡。這些屬性在部件中表示為this.props
瘟栖,在渲染方法中能夠動(dòng)態(tài)顯示數(shù)據(jù):
var MyComponent = React.createClass({
render: function(){
return (
<h1>Hello, {this.props.name}!</h1>
);
}
});
React.render(<MyComponent name="Handsome" />, document.getElementById('myDiv'));
部件生命周期和狀態(tài)
創(chuàng)建部件我們只需要render
方法即可,實(shí)際如果你想要部件發(fā)揮作用谅阿,我們有時(shí)需要部件的生命周期方法半哟。
生命周期方法
以下的生命周期方法你應(yīng)該了解:
- componentWillMount 激活一次,在客戶端&服務(wù)端渲染發(fā)生之前
- componentDidMount 激活一次签餐,在客戶端發(fā)生渲染之后
- shouldComponentUpdate 返回部件是否更新
- componentWillUnmount 在部件卸載之前激活
生命周期方法中的函數(shù)
- getInitialState 返回狀態(tài)的初始化值
- getDefaultProps 如果屬性沒有提供寓涨,設(shè)置回調(diào)屬性值
- mixins 對(duì)象數(shù)組,用以擴(kuò)展當(dāng)前部件的功能
狀態(tài)
每個(gè)部件都既有狀態(tài)state
也有屬性props
氯檐,設(shè)置狀態(tài)用setState
方法戒良。調(diào)用setState
會(huì)觸發(fā)UI更新。如果我們想在交互之前初始化部件狀態(tài)冠摄,可以用getInitialState
糯崎。下面,我們設(shè)置部件的狀態(tài):
var MyComponent = React.createClass({
getInitialState: function(){
return {
count: 5
}
},
render: function(){
return (
<h1>{this.state.count}</h1>
)
}
});
事件(Events)
React中河泳,事件作為屬性綁定到部件上沃呢,可以觸發(fā)方法。我們用事件來實(shí)現(xiàn)計(jì)數(shù):
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>
);
}
});
React.render(<Counter/>, document.getElementById('myDiv'));
上面的代碼演示在這兒拆挥。
單向數(shù)據(jù)流
React中薄霜,應(yīng)用數(shù)據(jù)流經(jīng)過state
和props
單向流動(dòng)。這意味著纸兔,在多層級(jí)部件頁面中惰瓜,父部件負(fù)責(zé)管理狀態(tài)并向下傳遞。
更新狀態(tài)使用setState
方法以確保UI的刷新食拜。結(jié)果值應(yīng)該以子部件屬性this.props
向下傳遞鸵熟。
/** @jsx React.DOM */
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>
)
}
});
React.render(<FilteredList/>, document.getElementById('myDiv'));
上面的示例代碼在這兒。
結(jié)論
上面介紹的是React基礎(chǔ)只是负甸,如需進(jìn)一步了解流强,可以閱讀React API和JSX痹届。
以上內(nèi)容來自于Learning React.js: Getting Started and Concepts。