前面已经写了一篇关于reactJS组件生命周期的博文,此篇博文是一个补充,增加了一些例子,有助于更好的理解reactJS组件。
**初始化阶段能够使用的钩子函数(按照触发顺序):**
**getDefaultProps**(获取实例的默认属性)————只有第一次实例的时候调用,实例之间共享引用(属性)
**getInitialState**(获取实例的初始状态)————初始化每个实例特有的状态
必须返回一个Object或者是Null
**componentWillMount**(组件即将被渲染到页面)——render之前最后一次修改状态的机会
**render**(组件在render中生成虚拟的DOM节点,即JSX,最后由React生成真实的DOM节点)——只能访问this.props和this.state,不应再访问其它信息,只有一个顶层组件,但是可以有子组件,不允许修改状态和DOM输出。
如果render需要修改状态和DOM输出,那么render就不能在服务端使用。并且,如果在render中修改状态和DOM输出,会使得代码逻辑变得复杂。所以,要尽可能避免这样做。
**componentDidMount**(组件被渲染到页面之后)——成功render并渲染完成真实DOM之后触发,可以修改DOM
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Keywords" content="关键词一,关键词二">
<meta name="Description" content="网站描述内容">
<meta name="Author" content="刘艳">
<title></title>
</head>
<body>
<div id = "example"></div>
<div id = "example2"></div>
</body>
</html>
<script src="build/jquery-1.11.2.min.js"></script>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var MyComponent = React.createClass({
getDefaultProps: function(){
console.log("获取实例的默认属性");
return{name: "Yvette"};
},
getInitialState: function () {
console.log("获取实例的初始状态");
return{will:true};
},
componentWillMount: function () {
console.log("组件即将被渲染到页面");
},
handleClick: function(event){
this.setState({will: !this.state.will});
},
componentDidMount: function(){
console.log("aaaa");
if(this.state.will){
$(this.refs.example).append("啦啦啦");
}else{
$(this.refs.example).append("郁闷");
}
},
render: function(){
console.log("render");
return(
<div>
<p ref = "example" onClick = {this.handleClick}>{this.props.name}未来{this.state.will ? "会" : "不会"}更好!</p>
</div>
)
}
});
ReactDOM.render(<MyComponent/>,document.querySelector("#example"));
ReactDOM.render(<MyComponent/>,document.querySelector("#example2"));
</script>
~~~
![](https://box.kancloud.cn/2016-04-07_5706040076301.jpg)
从运行结果可以看出:
1、获取默认属性(getDefaultProps)只会在第一次实例化组件时运行一次,后面不会再运行,
2、获取初始状态(getInitialState)和componentWillMount,render,componentDidMount在每次实例化组件时,都会进入.
3、点击切换时,只会触发render函数,因此我们写在componentDidMount函数中的状态判断不会再被执行.
**运行中阶段能够使用的钩子函数(按照触发顺序):**
**componentWillReceiveProps**(组件快要接收到属性时触发)——父组件修改属性触发,可以修改新属性、修改状态。
在修改发生之前出发。在属性真正比传送到组件之前,对其进行处理。
**shouldComponentUpdate**(组件接收到新状态时,是否需要更新,返回false,React就不会更新,可以提高性能)
**componentWillUpdate**(组件即将更新到页面)——不能修改属性和状态,会导致死循环
**render**——只能访问this.props和this.state,不应再访问其它信息,只有一个顶层组件,但是可以有子组件,不允许修改状态和DOM输出。
**componentDidUpdate**(在组件更新到页面之后调用)——可以修改DOM
~~~
<body>
<div id = "example"></div>
<div id = "example2"></div>
</body>
</html>
<script src="build/jquery-1.11.2.min.js"></script>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var MyComponent = React.createClass({
getDefaultProps: function(){
console.log("获取实例的默认属性");
return{name: "Yvette"};
},
getInitialState: function () {
console.log("获取实例的初始状态");
return{will:true};
},
componentWillMount: function () {
console.log("组件即将被渲染到页面");
},
handleClick: function(event){
this.setState({will: !this.state.will});
},
componentDidMount: function(){
console.log("组件被渲染到页面之后");
$(this.refs.example).append("啦啦啦");
},
render: function(){
console.log("render")
return(
<div>
<p ref = "example" onClick = {this.handleClick}>{this.props.name}未来{this.state.will ? "会" : "不会"}更好!</p>
</div>
);
},
componentWillReceiveProps: function(){
console.log("组件快要接收到属性");
},
shouldComponentUpdate: function(){
console.log("是否需要更新");
return false;
},
componentWillUpdate: function(){
console.log("组件即将被更新");
},
componentDidUpdate: function(){
console.log("组件更新被渲染到页面");
}
});
ReactDOM.render(<MyComponent/>,document.querySelector("#example"));
ReactDOM.render(<MyComponent/>,document.querySelector("#example2"));
</script>
~~~
运行结果如下:
![](https://box.kancloud.cn/2016-04-07_570604008875d.jpg)
从运行结果可以看出:
**1、在运行过程中,组件的状态发生改变时,首先进入shouldComponentUpdate函数,即组件是否需要更新,如果返回false,表示无需更新,直接返回。**
~~~
<body>
<div id = "example"></div>
<div id = "example2"></div>
</body>
</html>
<script src="build/jquery-1.11.2.min.js"></script>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var MyComponent = React.createClass({
getDefaultProps: function(){
console.log("获取实例的默认属性");
return{name: "Yvette"};
},
getInitialState: function () {
console.log("获取实例的初始状态");
return{will:true};
},
componentWillMount: function () {
console.log("组件即将被渲染到页面");
},
handleClick: function(event){
this.setState({will: !this.state.will});
},
componentDidMount: function(){
console.log("组件被渲染到页面之后");
//$(this.refs.example).append("啦啦啦");
},
render: function(){
console.log("render")
return(
<div>
<p ref = "example" onClick = {this.handleClick}>{this.props.name}未来{this.state.will ? "会" : "不会"}更好!</p>
<span ref = "more">啦啦啦</span>
</div>
);
},
componentWillReceiveProps: function(){
console.log("组件快要接收到属性");
},
shouldComponentUpdate: function(){
console.log("是否需要更新");
return true;
},
componentWillUpdate: function(){
console.log("组件即将被更新");
$(this.refs.example).css({"background": "#ccc","line-height":"30px"});
//this.setState({will: !this.state.will});//导致一个死循环
},
componentDidUpdate: function(){
console.log("组件更新被渲染到页面");
if(this.state.will){
$(this.refs.more).html("啦啦啦");
}
else{
$(this.refs.more).html("郁闷");
}
}
});
ReactDOM.render(<MyComponent/>,document.querySelector("#example"));
ReactDOM.render(<MyComponent/>,document.querySelector("#example2"));
</script>
~~~
![](https://box.kancloud.cn/2016-04-07_570604009b2f7.jpg)
从运行结果可以看出钩子函数的触发顺序:
1、shouldComponentUpdate,必须返回true或false,如果返回false,直接返回,不会再触发后面的钩子函数。
2、componentWillUpdate和componentDidUpdate中都可以操作DOM元素,因为当前在运行过程中,组件已经被渲染到了页面。但是最后是在componentDidUpdate中进行修改。
**销毁中阶段能够使用的钩子函数(按照触发顺序):**
**componentWillUnmount**(在销毁操作执行之前触发)——在组件真正被销毁前调用,在删除组件之前进行清理操作,如计时器和事件监听器。
~~~
<body>
<div id = "example"></div>
</body>
</html>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="build/browser.min.js"></script>
<script type="text/babel">
var style = {
color: "red",
border: "1px solid #000"
};
var HelloWorld = React.createClass({
render: function(){
return <p>Hello, {this.props.name ? this.props.name : "World"}</p>;
},
componentWillUnmount: function(){
console.log("I will unmount");
}
});
var HelloUniverse = React.createClass({
getInitialState: function(){
return {name: "Yvette"};
},
handleChange: function (event) {
if(event.target.value == "123"){
React.unmountComponentAtNode(document.querySelector("#example"))
return;
}
this.setState({name: event.target.value});
},
render: function(){
return(
<div>
<HelloWorld name = {this.state.name}></HelloWorld>
<br/>
<input type = "text" onChange = {this.handleChange} />
</div>
);
}
});
ReactDOM.render(<div style = {style}><HelloUniverse></HelloUniverse></div>,document.querySelector("#example"));
</script>
~~~
当输入结果为123时,触发componentWillUnmount钩子函数。
- 前言
- jQuery轮播图插件
- JS模拟事件操作
- JS闭包与变量
- JS绑定事件
- HTML5之file控件
- JavaScript的this词法
- JavaScript的this词法(二)
- JS this词法(三)
- JS检测浏览器插件
- JS拖拽组件开发
- number输入框
- Modernizr.js和yepnode.js
- DOM变化后事件绑定失效
- div和img之间的缝隙问题
- 详解JavaScript作用域
- bootstrap入门
- 表单验证(登录/注册)
- Bootstrap网格系统
- Bootstrap排版
- Bootstrap创建表单(一)
- Bootstrap表单(二)
- Bootstrap按钮
- Bootstrap图片
- Bootstrap字体图标(glyphicons)
- Bootstrap的aria-label和aria-labelledby
- Bootstrap下拉菜单
- Bootstrap按钮组
- Bootstrap按钮菜单
- Bootstrap输入框组
- Bootstrap导航元素
- Bootstrap导航栏
- sublimeText频频崩溃
- JQuery不同版本的差异(checkbox)
- Bootstrap面包屑导航、分页、标签、徽章
- Bootstrap警告
- Bootstrap进度条
- 前端的上传下载
- JS字符串的相关方法
- CSS3选择器(全)
- CSS3新增文本属性详述
- 利用CSS3实现图片切换特效
- CSS3新增颜色属性
- CSS3的border-radius属性详解
- JS创建对象几种不同方法详解
- JS实现继承的几种方式详述(推荐)
- CSS3响应式布局
- JS模块化开发(requireJS)
- 利用@font-face实现个性化字体
- 前端在html页面之间传递参数的方法
- CSS自动换行、强制不换行、强制断行、超出显示省略号
- 如何在Html中引入外部页面
- reactJS入门
- React组件生命周期
- 使用React实现类似快递单号查询效果
- ReactJS组件生命周期详述
- React 属性和状态详解