React入门教程
<!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组件有两个span子节点,它们都可以通过this.props.children获取。
注意:this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined ;如果有一个子节点,数据类型是 object ;如果有多个子节点,数据类型就是 array 。所以,处理 this.props.children 的时候要小心。
不过,React为我们提供了React.Children工具方法来处理this.props.children。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是 object。更多的 React.Children 的方法,请参考官方文档。
5.3 获取真实的DOM节点
在React里,其引入了虚拟DOM(Virtual DOM)的机制。所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,React都会重新构建整个DOM树,然后React将当前整个DOM树和上一次的DOM树进行对比,得到DOM结构的区别,然后仅仅将需要变化的部分进行实际的浏览器DOM更新,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
有时,我们需要从组件内获取真实的DOM节点,这时就要用到 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")
);
输出:
上面代码中,我们需要点击按钮来获取文本输入框的值。这时,由于虚拟 DOM 是拿不到用户输入的,所以我们就必须获取真实的 DOM 节点。而在React里,我们是通过给DOM添加 ref 属性,然后在组件类中,使用this.refs.[refName] ,就会返回这个真实的 DOM 节点。
需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。
React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等,完整的事件清单请查看官方文档。
5.4 this.state
React 把用户界面当作简单状态机。把用户界面想像成拥有不同状态然后渲染这些状态,可以轻松让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。React 来决定如何最高效地更新 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>
);
}
});
上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。
5.5 表单
诸如 <input>、<textarea>、<option> 这样的表单组件不同于其他组件,因为他们可以通过用户交互发生变化。这些组件提供的界面使响应用户交互的表单数据处理更加容易。
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 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况,更多介绍请参考官方文档。