React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。
由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单。所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具。
一、组件的生命周期
组件的生命周期分成三个状态:
Mounted:React Components被render解析生成对应DOM节点并被插入浏览器的DOM结构的一个过程。
Updated:一个mounted的React Components被重新render的过程。
Unmounted:一个mounted的React Components对应的DOM节点被从DOM结构中移除的这样一个过程。
Mounting:已插入真实 DOM
Updating:正在被重新渲染
Unmounting:已移出真实 DOM
React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数。(getInitialState()用来初始化React Components的state)
componentWillMount() //mounting前被调用
componentDidMount() //mounted后被调用
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()//可以执行释放资源等操作,一般很少用(应为浏览器有自己的垃圾回收机制)。
示例代码如下:
<!DOCTYPE html>
<html>
<head>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
var Hello = React.createClass({
//getInitialState()用来初始化React Components的state
getInitialState: function() {
alert('init');
return {
opacity: 0.5,
fontSize:'40px'
};
},
render: function() {
//应用初始的state:两种方式
// return <div style={this.state}>Hello {this.props.name}</div>;
return <div style={{opacity:this.state.opacity,fontSize:this.state.fontSize}}>Hello {this.props.name}</div>;
},
componentWillMount:function() {
alert('will');
},
componentDidMount:function() {
alert('did');
var _self=this;//在window.setTimeout函数参数之外this代表当前的Component的实例,在window.setTimeout函数之内时表示当前运行环境的global对象(对于当前浏览器来说就是window对象),所以要用_self把this保存下来
window.setTimeout(function(){
_self.setState({
opacity: 0.5,
fontSize:'80px'
});
},1000);
}
});
ReactDOM.render(
<Hello name="World"/>,
document.getElementById('container')
);
</script>
</body>
</html>
此外,React 还提供两种特殊状态的处理函数。
(1)componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
(2)shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用
这些方法的详细说明,可以参考官方文档。下面是一个例子:
<!DOCTYPE html>
<html>
<head>
<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">
var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
},
componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1) {
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
},
render: function () {
return (
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
</div>
);
}
});
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('example')
);
</script>
</body>
</html>
部分代码如下:
var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
},
componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1) {
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
},
render: function () {
return (
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
</div>
);
}
});
ReactDOM.render(
<Hello name="world"/>,
document.body
);
上面代码在hello组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染。
另外,组件的style属性的设置方式也值得注意,不能写成:
style="opacity:{this.state.opacity};"
而要写成:
style={{opacity: this.state.opacity}}
这是因为 React 组件样式是一个对象,所以第一重大括号表示这是 JavaScript 语法,第二重大括号表示样式对象。
二、事件处理
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/babel">
var TestClickComponent=React.createClass({
handleClick:function(event){
var tipE=React.findDOMNode(this.refs.tip);
if(tipE.style.display==='none'){
tipE.style.display='inline';
}else{
tipE.style.display='none';
}
event.stopPropagation();<!--停止冒泡-->
event.preventDefault();<!--阻止默认动作-->
},
render:function(){
return(
<div>
<button onClick={this.handleClick}>显示|隐藏</button><span ref="tip">测试点击</span>
<!--onClick驼峰式绑定;利用ref属性给子组件起名字,然后通过this.refs来索引-->
</div>
);
}
});
var TestInputComponent=React.createClass({
getInitialState: function() {
return {
inputContent:''
}
},
changeHandler:function(event){
this.setState({
inputContent:event.target.value
});
event.stopPropagation();<!--停止冒泡-->
event.preventDefault();<!--阻止默认动作-->
},
render: function() {
return(
<div>
<input type="text" onChange={this.changeHandler} /><span>{this.state.inputContent}</span>
</div>
);
}
});
ReactDOM.render(
<div>
<TestClickComponent/>
<br/>
<br/>
<br/>
<br/>
<TestInputComponent/>
</div>,
document.getElementById('container'));
</script>
</body>
</html>