先放一些前期看过的以及正在看的资料,初学者,会一边学习一边实践。
从来都没有学过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}>Deletebutton> //注意这个是用的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}>Deletebutton> //注意这个是用的this
li>;
})
}
</ul>
);
}
对于一个近期在写C++的人来说,上面的代码毫无违和感,但是问题来了。
下面这个this到底是谁的上下文呢?答案:当前function内的。所以上面的代码为什么点击按钮没有触发对应的代码,就是因为没有当前function里没有这个函数。而我们的意思是要找到外面的deleteProgram函数。这就是为什么需要用这句代码:
var that = this; //去掉这行有惊喜
在进入一个新的函数前,先用这行代码把之前的上下文保存下来,否则this会被更新成当前的function的this。
晚上写完代码补充
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时爬过的坑即可,也是本博客的本意。