前面已經寫了一篇關于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"};
},
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>
~~~
運行結果如下:?
?
從運行結果可以看出:?
**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,如果返回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 屬性和狀態詳解