簡介
學(xué)完這篇博文浪腐,你可以對React,這個著名的Facebook的庫有一定程度的理解顿乒,并能開始實踐议街。再完成后續(xù)的學(xué)習(xí)之后你可以掌握React。在正式開始以前璧榄,先了解一些相關(guān)的概念特漩。
什么是React?
React是一個Facebook開發(fā)的UI庫骨杂。使用這個庫可以很方便的開發(fā)交互式的涂身、具有表達力的和可重用的UI組件。并且這個庫已經(jīng)在facebook和instagram.com的產(chǎn)品中使用腊脱。
這個庫的另外一個獨特的賣點是:他不僅可以使用在客戶端访得,還可以用在Server端渲染。
這個庫還使用了一種叫做虛擬DOM(Virtual DOM)的概念陕凹,這些DOM可以根據(jù)狀態(tài)有選擇的渲染。這樣鳄炉,頁面就會盡量的減少DOM操作而達到保持頁面狀態(tài)的效果杜耙。
虛擬DOM是如何工作的
想象一下你根據(jù)一個人造了一個模特,這個模特幾乎有這個人的全部屬性拂盯,并且有這個人的所有當(dāng)前狀態(tài)佑女。這基本上就是React的虛擬DOM做的。
現(xiàn)在假設(shè)你對這個人形模特做了某些修改。比如团驱,加了胡子摸吠、強壯的二頭肌。在React的世界里嚎花,當(dāng)我們做了這些修改寸痢,會發(fā)生兩件事:第一、運行“對比”算法找出發(fā)生的改變紊选。第二啼止、調(diào)整,根據(jù)第一步找出的不同執(zhí)行必要的DOM操作兵罢。
React工作的方式不是把真人拿來從頭到尾的來一次“整形”献烦,而是只修改臉(帖胡子)和胳膊(二頭肌)卖词。也就是如果你在input里加了文字巩那,之后開始渲染操作里,如果input的父節(jié)點沒有開始上文第二步的“調(diào)整”操作此蜈,那么input里的文字是不會動的即横。
因為React使用的是假的DOM不是真的,這也給了React一個新的可能舶替。我們可以在Server端渲染這些假DOM令境。
現(xiàn)在開始
開始React之旅非常簡單,主要下載facebook提供的開始示例:
你也可以用他們提供的JSFiddle:
建立頁面
稍后使用的練習(xí)頁面需要包括react.js
顾瞪、react-dom.js
和
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id='mount-point'>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
<script type="text/babel">
</script>
</body>
</html>
react-dom
是最近發(fā)布的React的支持庫舔庶。react-dom
本來是react.js的一部分,后來作為單獨的庫發(fā)布陈醒。
在React里惕橙,一個組件就是一個元素,所以在本例中我們可以使用mount-point
div作為父容器钉跷。
本例只是作為入門時使用的弥鹦,在實際的開發(fā)中最好是把創(chuàng)建的組件都放在一個單獨的文件中。
基本內(nèi)容
React的基本創(chuàng)建單元叫做組件爷辙,例如:
<script type="text/babel">
ReactDOM.render(
<h1>Hello, World!</h1>,
document.getElementById('mount-point')
);
</script>
如果你從沒見過這樣的寫法彬坏,你會以為javascript/HTML又有什么新的魔法了。
JSX
其實這是JSX膝晾,是一個javascript的XML變體栓始。使用JSX可以在javascript里寫出HTML式的標簽。
在JSX里血当,HTML的class
屬性寫成className
幻赚,for
屬性寫成htmlFor
禀忆,因為class
, for
都是javascript的關(guān)鍵字。更多不同的內(nèi)容可以在這里看到落恼。
你也可以不使用JSX箩退,這是一個不用JSX的例子:
ReactDOM.render(
React.createElement('h1', null, 'Hello!'),
document.getElementById('content')
);
組件
使用ReactDOM的render
方法的時候,第一個參數(shù)是需要渲染的我們創(chuàng)建的組件佳谦,第二個是HTML的DOM節(jié)點戴涝,組件渲染之后在這里添加。我們可以使用createClass
方法創(chuàng)建組件吠昭。創(chuàng)建組件方法只需要一個對象作為參數(shù)喊括。我們來創(chuàng)建一個:
var MyComponent = React.createClass({
render: function(){
return (
<h1>Hello, world!</h1>
);
}
});
組件創(chuàng)建好之后就可以在文檔里渲染出來了:
ReactDOM.render(
<MyComponent />,
document.getElementById('mount-point')
);
很酷吧!矢棚?
進階
創(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')
);
生命周期和狀態(tài)
render
方法是創(chuàng)建組件的唯一方法兜粘,另外還有一些生命周期相關(guān)的方法可以使用申窘。
生命周期方法
- componentWillMount 在渲染之前調(diào)用一次。
- componentDidMount 在渲染之后調(diào)用一次孔轴。
- shouldComponentUpdate 返回值決定組件是否需要update剃法。
- componentWillUnmount 在卸載組件之前調(diào)用。
狀態(tài)(State)
在開始State之前路鹰,需要了解一些相關(guān)基礎(chǔ):
- getInitialState返回State的初始值贷洲。
- getDefaultProps獲取props的初始值。
- mixins一組對象晋柱,主要用來擴展當(dāng)前組件的功能优构。
更多相關(guān)的的內(nèi)容可以看這里。
每一個組件都包含一個state
對象和一個props
對象雁竞。State(狀態(tài))用setState
方法設(shè)置钦椭。調(diào)用setState
方法會觸發(fā)UI的更新,也是實現(xiàn)交互式開發(fā)的必要基礎(chǔ)碑诉。如果我們要在一開始設(shè)定初始狀態(tài)(initial state)彪腔,可以調(diào)用getInitialState
方法。代碼:
var MyComponent = React.createClass({
getInitialState:function(){
return {
count: 5
};
},
render: function(){
return (
<h1>Hello, {this.state.count}!</h1>
);
}
});
事件
React包含一個跨瀏覽器的事件系統(tǒng)进栽。這些事件作為屬性包含在組件中漫仆。代碼:
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')
);
單向數(shù)據(jù)流
在Rect里,數(shù)據(jù)通過state
和props
單向流動泪幌,這和Angular的雙向流動不同盲厌。也就是說,在一個多組件結(jié)構(gòu)里祸泪,一個父組件需要負責(zé)管理狀態(tài)(state)并把數(shù)據(jù)通過props向下發(fā)放吗浩。
組件的狀態(tài)應(yīng)該用setState
方法更新,這樣可以確保UI會同時刷新没隘。數(shù)據(jù)通過設(shè)置子組件的屬性來傳遞給子組件懂扼。子組件可以通過this.props
來獲取這些數(shù)據(jù)。代碼:
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'));
結(jié)語
現(xiàn)在我們已經(jīng)把React的基礎(chǔ)都學(xué)會了右蒲,花點時間看看React API和JSX阀湿。
原文地址:https://scotch.io/tutorials/learning-react-getting-started-and-concepts