2015-09-23 31 views
4

我跟隨React Beginner Tutorial,我試圖把它翻譯成ES6。但是,當我將CommentBox更改爲ES6類時,它開始給我一個this.props.url錯誤(在loadCommentsFromServer的AJAX調用中)爲undefined錯誤。我認爲這與ES6如何綁定this有關,但是我對語言(和React)不是很熟悉,所以我不確定。我看了看React 0.13 release notes,看到這一點:ES6 /反應「這個」關鍵字與AJAX從服務器獲取數據(教程)

React.createClass有一個內置的神奇功能,可以自動綁定的所有方法this你。對於其他類中不習慣此功能的JavaScript開發人員來說,這可能會有些混亂,或者當他們從React移動到其他類時會引起混淆。

我不能完全肯定,但我認爲,這意味着我必須這樣做的值保存(如let that = this.bind(that)),但也作出了同樣的this.props.urlundefined - 我不知道在哪裏下一步。

這裏是我當前的代碼:

class CommentBox extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     data: [] 
    }; 
    } 
    loadCommentsFromServer() { 
    $.ajax({ 
     url: this.props.url, 
     dataType: 'json', 
     cache: false, 
     success: function(data) { 
     this.setState({ 
      data: data 
     }) 
     }.bind(this) 
    }); 
    } 
    handleCommentSubmit(comment) { 
    var comments = this.state.data; 
    var newComments = comments.concat([comment]); 
    this.setState({ data: newComments }); 
    $.ajax({ 
     url: this.props.url, 
     dataType: 'json', 
     type: 'POST', 
     data: comment, 
     success: function(data) { 
     this.setState({ data: data }); 
     }, 
     error: function(xhr, status, err) { 
     console.error(this.props.url, status, err.toString()); 
     }.bind(this) 
    }); 
    } 
    componentDidMount() { 
    this.loadCommentsFromServer(); 
    setInterval(this.loadCommentsFromServer, this.props.pollInterval); 
    } 
    render() { 
    return (
     <div className="commentBox"> 
     <h1>Comments</h1> 
     <CommentList data={this.state.data}/> 
     <CommentForm onCommentSubmit={this.handleCommentSubmit}/> 
     </div> 
    ); 
    } 
}; 

回答

5

您需要使用bind(this)來綁定您的活動。如下圖所示:

componentDidMount() { 
    this.loadCommentsFromServer().bind(this); 
    setInterval(this.loadCommentsFromServer.bind(this), this.props.pollInterval); 
    } 

你可以閱讀從這個鏈接引用: https://facebook.github.io/react/docs/reusable-components.html#no-autobinding

沒有自動綁定 方法遵循相同的語義規則ES6類,這意味着它們不會自動綁定到這個實例。您必須明確使用.bind(this)或箭頭函數=>。

+0

由於我不能在這個實例中使用箭頭函數,我猜'bind(this)'是唯一的解決方案? – nathanhleung

+0

我犯了一個錯誤之前,「this.loadCommentsFromServer()」不能綁定(這)。 –

+0

順便說一句,如果你想使用箭頭函數,唯一的方法是這樣的:setInterval((=)=> {$ .ajax({url:this.props.url, dataType:'json', cache:false , 成功:功能(數據){ this.setState({ 數據:數據 }) } .bind(本) });},this.props.pollInterval); –

0

內的類似成功和錯誤,範圍的變更回調函數,所以「這種」不再是CommentBox。

你需要做的是這樣的:

handleCommentSubmit(comment) { 
    var comments = this.state.data; 
    var newComments = comments.concat([comment]); 
    this.setState({ data: newComments }); 
    var comment_box = this; 
    $.ajax({ 
     url: this.props.url, 
     dataType: 'json', 
     type: 'POST', 
     data: comment, 
     success: function(data) { 
     comment_box.setState({ data: data }); 
     }, 
     error: function(xhr, status, err) { 
     console.error(comment_box.props.url, status, err.toString()); 
     }.bind(this) 
    }); 
    } 

應用此到其他適用的地方在你的代碼

+0

它是用ES5和'React.createClass'編寫的,ES6中的任何內容都改變了'this'綁定到回調函數的方式嗎? – nathanhleung

+0

我不確定。我建議在回調函數中添加console.log(this),以便驗證「this」是什麼。 –

+0

好吧,這個''工程一次(它顯示正確的對象),然後它開始給我未定義的錯誤 – nathanhleung

1

這是一個針對執行React.Component作爲ES6類的特定行爲。當使用ES5風格時,React組件會自動綁定所有的功能。當您使用ES6類風格時,唯一的自動回彈方法是React.Componentrender,componentDidMount等)中特別包含的方法。

這實際上是mentioned in the documentation,雖然很容易忽視。

不要覺得不舒服;我知道它在文檔中,因爲我第一次將一些工作的React組件移植到ES6類中時,我必須去找它。