一,相關學習資料
先放一些前期看過的以及正在看的資料,初學者,會一邊學習一邊實踐。
二,javascript深坑
從來都沒有學過javascript,寫倒是寫了一些,所以下面提及那個坑也是被坑得心服口服。
問題描述:
在給button設置onClick點擊行爲的時候,點擊按鈕死活執行對應的函數,Google了一下,在stack-overflow上找到一些類似的問題,英文是when I click the button, it don’t fired(覺得fired好玩就摘抄了下來)。
不多說,直接上正確代碼。
deleteProgram: function(){
alert("delete");
},
render: function(){
var that = this; //去掉這行有驚喜
return(
<ul>
{
this.state.programs.map(function(bill,index) {
return <li>
<ChannelProgram start_time={bill["start_time"]} end_time={bill["end_time"]} title={bill["program"]["name"]}/>
<button onClick={that.deleteProgram} value={index}>Delete</button> //注意這個是用的that
</li>;
})
}
</ul>
);
}
注意第五行代碼(話說markdown怎麼添加代碼行號,求指點,這裏網速不好就先不Google了,以後找到會再分享,12月9日更新,發了博客後會自動加上代碼行號)
var that = this; //去掉這行有驚喜
下面是錯誤的代碼:
deleteProgram: function(){
alert("delete");
},
render: function(){
return(
<ul>
{
this.state.programs.map(function(bill,index) {
return <li>
<ChannelProgram start_time={bill["start_time"]} end_time={bill["end_time"]} title={bill["program"]["name"]}/>
<button onClick={this.deleteProgram} value={index}>Delete</button> //注意這個是用的this
</li>;
})
}
</ul>
);
}
對於一個近期在寫C++的人來說,上面的代碼毫無違和感,但是問題來了。
<button onClick={this.deleteProgram} value={index}>Delete</button> //注意這個是用的this
下面這個this到底是誰的上下文呢?答案:當前function內的。所以上面的代碼爲什麼點擊按鈕沒有觸發對應的代碼,就是因爲沒有當前function裏沒有這個函數。而我們的意思是要找到外面的deleteProgram函數。這就是爲什麼需要用這句代碼:
var that = this; //去掉這行有驚喜
在進入一個新的函數前,先用這行代碼把之前的上下文保存下來,否則this會被更新成當前的function的this。
- javascript的this是當前function內的上下文。
- javascript的this是當前function內的上下文。
- javascript的this是當前function內的上下文。
三,React複合組件內容更新的坑
晚上寫完代碼補充
12月9日更新,果然晚上是沒有時間補上的,趁現在有時間趕緊寫下來。問題描述:
在複合組件裏,即便父級組件刷新了(調用了render函數來刷新界面),子級組件的值也不更新。
老規矩,不多說,直接上代碼。
Channel部分代碼
render: function(){
var that = this;
return(
<ul>
{
this.state.programs.map(function(bill,index) {
return <li><ChannelProgram change={that.props.change} start_time={bill["start_time"]} end_time={bill["end_time"]} title={bill["program"]["name"]}/></li>;
})
}
</ul>
);
}
ChannelProgram組件內部代碼
var ChannelProgram = React.createClass({
getInitialState: function() {
return {
start_time: this.props.start_time,
end_time: this.props.end_time,
title: this.props.title
}
},
componentWillReceiveProps: function(nextProps,nextState) {
this.setState({
start_time: nextProps.start_time,
end_time: nextProps.end_time,
title: nextProps.title
});
},
render: function(){
var start_time = this.state.start_time;
var end_time = this.state.end_time;
var title = this.state.title;
return(
<div>
<input id="start_time" value={start_time} onChange={this.props.change}/>
<input id="end_time" value={end_time} onChange={this.props.change}/>
<input id="title" value={title} onChange={this.props.change}/>
</div>
);
}
});
注意上面ChannelProgram裏面的第十行開始的函數,更新子組件的關鍵:
componentWillReceiveProps: function(nextProps,nextState) {
this.setState({
start_time: nextProps.start_time,
end_time: nextProps.end_time,
title: nextProps.title
});
}
如果看過開頭提及的資料《React生命週期》,那一切問題都不是問題了,所以像我這種新手還是要先看文檔再上手寫代碼省事得多,不過項目進度要跟上,暫且現學現用。
componentWillReceiveProps,理解意思即可,組件收到新的props時會觸發(即當父級組件render刷新了子組件的props時觸發),此時更新狀態,大功告成。
好了,看似簡單,我說說我的想法和困惑的地方。一開始我是沒有加上這個函數的,導致子組件內容不更新,很疑惑,明明父級組件的render刷新了,子組件就是不更新。後來在子組件的getInitialState函數裏面輸出log,發現無論父級組件更新了多少次,子組件的getInitialState只會執行一遍。恍然大悟,React的刷新機制是重用已有組件而不是重新新建組件(如果新建組件的話,每次刷新getInitialState都會被調用),如果一開始就從React的原理出發考慮問題,就不會走彎路了,不過彎路走得越多越深刻吧,加油就好!
四,其他
這裏提到的坑都不是React和javascript的問題,都是自己學藝不精所致,說是React和javascript的坑只是自嘲一下,理解爲我在學習React和javascript時爬過的坑即可,也是本博客的本意。