<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>react</title>
<script src="react/react.js"></script>
<script src="react/react-dom.js"></script>
<script src="react/browser.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
/*your code*/
</script>
</body>
</html>
<script type="text/babel">
ReactDOM.render(
<h1>Hellow World!</h1>,
document.getElementById("example")
);
</script>
<script type="text/babel">
var names=['Alice','Emily','Kate'];
ReactDOM.render(
<div>
{
names.map(function(name){
return <div>Hello {name}</div>
})
}
</div>,
document.getElementById("example")
);
</script>
var arr=[
<h1>Hello World</h1>,
<h2>React</h2>
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById("example")
);
var HelloMessage=React.createClass({
render:function(){
return <h1>Hello {this.props.name}</h1>
}
});
ReactDOM.render(
<HelloMessage name="Dennis"/>,
document.getElementById('example')
);
var HelloMessage=React.createClass({
render:function(){
return <h1 style={{color:this.props.color}}>Hello {this.props.name}</h1>
}
});
ReactDOM.render(
<HelloMessage name="Dennis" color="red"/>,
document.getElementById('example')
);
var NotesList=React.createClass({
render:function(){
return (
<ul>
{
React.Children.map(this.props.children,function(child){
return <li>{child}</li>;
})
}
</ul>
);
}
});
ReactDOM.render(
<NotesList>
<span>Hello</span>
<span>World</span>
</NotesList>,
document.body
);
輸出:
在上面的代碼中,NotesList組件有兩個(gè)span子節(jié)點(diǎn),它們都可以通過(guò)this.props.children獲取。
注意:this.props.children 的值有三種可能:如果當(dāng)前組件沒有子節(jié)點(diǎn),它就是 undefined ;如果有一個(gè)子節(jié)點(diǎn),數(shù)據(jù)類型是 object ;如果有多個(gè)子節(jié)點(diǎn),數(shù)據(jù)類型就是 array 。所以,處理 this.props.children 的時(shí)候要小心。
不過(guò),React為我們提供了React.Children工具方法來(lái)處理this.props.children。我們可以用 React.Children.map 來(lái)遍歷子節(jié)點(diǎn),而不用擔(dān)心 this.props.children 的數(shù)據(jù)類型是 undefined 還是 object。更多的 React.Children 的方法,請(qǐng)參考官方文檔。
5.3 獲取真實(shí)的DOM節(jié)點(diǎn)
在React里,其引入了虛擬DOM(Virtual DOM)的機(jī)制。所有的DOM構(gòu)造都是通過(guò)虛擬DOM進(jìn)行,每當(dāng)數(shù)據(jù)變化時(shí),React都會(huì)重新構(gòu)建整個(gè)DOM樹,然后React將當(dāng)前整個(gè)DOM樹和上一次的DOM樹進(jìn)行對(duì)比,得到DOM結(jié)構(gòu)的區(qū)別,然后僅僅將需要變化的部分進(jìn)行實(shí)際的瀏覽器DOM更新,這種算法叫做 DOM diff ,它可以極大提高網(wǎng)頁(yè)的性能表現(xiàn)。
有時(shí),我們需要從組件內(nèi)獲取真實(shí)的DOM節(jié)點(diǎn),這時(shí)就要用到 ref 屬性。
var MyFrom=React.createClass({
handleClick:function(){
console.log(this.refs.tel.value);
},
render:function(){
return(
<div>
<input type="text" ref="tel"/>
<input type="button" value="獲取電話" onClick={this.handleClick}/>
</div>
);
}
});
ReactDOM.render(
<MyFrom/>,
document.getElementById("example6")
);
輸出:
上面代碼中,我們需要點(diǎn)擊按鈕來(lái)獲取文本輸入框的值。這時(shí),由于虛擬 DOM 是拿不到用戶輸入的,所以我們就必須獲取真實(shí)的 DOM 節(jié)點(diǎn)。而在React里,我們是通過(guò)給DOM添加 ref 屬性,然后在組件類中,使用this.refs.[refName] ,就會(huì)返回這個(gè)真實(shí)的 DOM 節(jié)點(diǎn)。
需要注意的是,由于 this.refs.[refName] 屬性獲取的是真實(shí) DOM ,所以必須等到虛擬 DOM 插入文檔以后,才能使用這個(gè)屬性,否則會(huì)報(bào)錯(cuò)。上面代碼中,通過(guò)為組件指定 Click 事件的回調(diào)函數(shù),確保了只有等到真實(shí) DOM 發(fā)生 Click 事件之后,才會(huì)讀取 this.refs.[refName] 屬性。
React 組件支持很多事件,除了 Click 事件以外,還有 KeyDown 、Copy、Scroll 等,完整的事件清單請(qǐng)查看官方文檔。
5.4 this.state
React 把用戶界面當(dāng)作簡(jiǎn)單狀態(tài)機(jī)。把用戶界面想像成擁有不同狀態(tài)然后渲染這些狀態(tài),可以輕松讓用戶界面和數(shù)據(jù)保持一致。
React 里,只需更新組件的 state,然后根據(jù)新的 state 重新渲染用戶界面(不要操作 DOM)。React 來(lái)決定如何最高效地更新 DOM。
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});
上面代碼是一個(gè) LikeButton 組件,它的 getInitialState 方法用于定義初始狀態(tài),也就是一個(gè)對(duì)象,這個(gè)對(duì)象可以通過(guò) this.state 屬性讀取。當(dāng)用戶點(diǎn)擊組件,導(dǎo)致狀態(tài)變化,this.setState 方法就修改狀態(tài)值,每次修改以后,自動(dòng)調(diào)用 this.render 方法,再次渲染組件。
由于 this.props 和 this.state 都用于描述組件的特性,可能會(huì)產(chǎn)生混淆。一個(gè)簡(jiǎn)單的區(qū)分方法是,this.props 表示那些一旦定義,就不再改變的特性,而 this.state 是會(huì)隨著用戶互動(dòng)而產(chǎn)生變化的特性。
5.5 表單
諸如 <input>、<textarea>、<option> 這樣的表單組件不同于其他組件,因?yàn)樗麄兛梢酝ㄟ^(guò)用戶交互發(fā)生變化。這些組件提供的界面使響應(yīng)用戶交互的表單數(shù)據(jù)處理更加容易。
var Input = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function () {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
ReactDOM.render(<Input/>, document.body);
上面代碼中,文本輸入框的值,不能用 this.props.value 讀取,而要定義一個(gè) onChange 事件的回調(diào)函數(shù),通過(guò) event.target.value 讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬于這種情況,更多介紹請(qǐng)參考官方文檔。
更多建議: