ReactJS修煉之路(一)

一,相關學習資料

先放一些前期看過的以及正在看的資料,初學者,會一邊學習一邊實踐。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章