ReactJS修炼之路(一)

来源:互联网 发布:linux smp lock.h 编辑:程序博客网 时间:2024/05/20 00:11

一,相关学习资料

先放一些前期看过的以及正在看的资料,初学者,会一边学习一边实践。

  • 官方文档
  • 官方入门教程
  • React生命周期

二,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时爬过的坑即可,也是本博客的本意。

0 0
原创粉丝点击