前面已经写了一篇关于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>
从运行结果可以看出:
**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"}; },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("#example2")); </script>
运行结果如下:
从运行结果可以看出:
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>
从运行结果可以看出钩子函数的触发顺序:
1、shouldComponentUpdate,必须返回true或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钩子函数。