2016-01-08 72 views
1

在我的情況下,TopicList是一個父組件,而IndividualTopic是一個子組件。當用戶點擊子組件時,它將showTopicDescription的狀態更改爲true。但是,如何將showTopicDescription的值傳遞給父組件(TopicList)或直接設置父組件狀態?如何在React中設置父組件的狀態

var TopicsList = React.createClass({ 

    render: function() { 
     return (
      <div className="row"> 
       <IndividualTopic topic_no="1"> 
        Topic 1 
       </IndividualTopic> 
       <IndividualTopic topic_no="2"> 
        Topic 2 
       </IndividualTopic> 
       <IndividualTopic topic_no="3"> 
        Topic 3 
       </IndividualTopic> 
       <IndividualTopic topic_no="4"> 
        Topic 4 
       </IndividualTopic> 
       <div className="col-sm-12"> 
        { this.state.showTopicDescription ? <IndividualTopicPages /> : null } 
       </div> 
      </div> 
     ); 
    } 
}); 

var selected_topic_no; 

var IndividualTopic = React.createClass({ 
    getInitialState: function() { 
     return { showTopicDescription: false }; 
    }, 
    onClick: function() { 
     this.setState({ showTopicDescription: true }); 
     selected_topic_no = this.props.topic_no - 1; 
    }, 
    render: function() { 
     return (
      <div> 
       <div className="col-sm-2"> 
        <div onClick={this.onClick} className="single-topic" data-topic-no={this.props.topic_no}> 
         {this.props.children} 
        </div> 
       </div> 
      </div> 
     ); 
    } 

}); 
+0

參見:https://facebook.github.io/react/tips/communicate-between-components.html – Simone

+0

@simone我在那個鏈接期待已久以前,但我不明白如何實現我案件。 –

回答

2

從IndividualTopic的點擊處理程序調用使用this.props這是我們在父component.Refer的下面的代碼渲染方法進行註冊父組件上setTopicDescription功能 -

var TopicsList = React.createClass({ 
    setTopicDescription: function(topicDescription){ 
    //HERE WE GET THE TOPIC DESCRIPTION FLAG. CHEEERS WE CAN DO WHAT WE NEED OVER HERE 
    }, 
    render: function() { 
     return (
      <div className="row"> 
       <IndividualTopic topic_no="1" setTopicDescription={this.setTopicDescription} > 
        Topic 1 
       </IndividualTopic> 
       <IndividualTopic topic_no="2" setTopicDescription={this.setTopicDescription}> 
        Topic 2 
       </IndividualTopic> 
       <IndividualTopic topic_no="3" setTopicDescription={this.setTopicDescription}> 
        Topic 3 
       </IndividualTopic> 
       <IndividualTopic topic_no="4" setTopicDescription={this.setTopicDescription}> 
        Topic 4 
       </IndividualTopic> 
       <div className="col-sm-12"> 
        { this.state.showTopicDescription ? <IndividualTopicPages /> : null } 
       </div> 
      </div> 
     ); 
    } 
}); 

var selected_topic_no; 

var IndividualTopic = React.createClass({ 
    getInitialState: function() { 
     return { showTopicDescription: false }; 
    }, 
    onClick: function() { 
     this.setState({ showTopicDescription: true }); 
     selected_topic_no = this.props.topic_no - 1; 
     this.props.setTopicDescription({ showTopicDescription: true }); 
    }, 
    render: function() { 
     return (
      <div> 
       <div className="col-sm-2"> 
        <div onClick={this.onClick} className="single-topic" data-topic-no={this.props.topic_no}> 
         {this.props.children} 
        </div> 
       </div> 
      </div> 
     ); 
    } 

}); 
+0

我收到一個錯誤「Uncaught ReferenceError:setTopicDescription is not defined」 –

+0

如果您打算進行純封裝,您可能會爭辯說IndividualTopic應該只是從TopicsList傳遞一個回調函數作爲prop。然後將selected_topic_no和showTopicDescription綁定到IndividualTopic中的道具。 – jolyonruss

+0

@jolyonruss如果你能舉一個例子,那將是非常值得讚賞的。 –

0

這裏有一個註釋後續版本根據我的評論。

我已經添加了一堆評論,隨意問任何更多的問題,我試圖解決的主要問題是,IndividualTopic組件應該是愚蠢的,並且它裏面的邏輯很少,只是通過道具並調用回調。

這是徹底未經測試的僞代碼,請不要期望它按原樣工作 - 我只是試圖說明一種方法。

var TopicsList = React.createClass({ 

    // setup our generic callback method to handle all topic selection 
    // this gets passed the event object and topic ID and sets the state 
    topicSelectionCallback: function(topicID, event) { 
     this.setState({ 
      showTopicDescriptions: true, 
      selectedTopicID: topicID 
     }); 
    }, 

    // maybe you need to close the topic as well... 
    closeTopicCallback() { 
     this.setState({ 
      showTopicDescription: false 
     }); 
    } 

    render: function() { 
     return (
      <div className="row"> 
       // I've neatened up your syntax for the IndividualTopic elements 
       // props should be camel case and one their own line, I pass 
       // through the callback as well as the label 
       <IndividualTopic 
        topicID="1" 
        selectionCallback={this.topicSelectionCallback} 
        label="Topic" 
       > 
       <IndividualTopic 
        topicID="2" 
        selectionCallback={this.topicSelectionCallback} 
        label="Topic" 
       > 
       <IndividualTopic 
        topicID="3" 
        selectionCallback={this.topicSelectionCallback} 
        label="Topic" 
       > 
       <IndividualTopic 
        topicID="4" 
        selectionCallback={this.topicSelectionCallback} 
        label="Topic" 
       > 
       <div className="col-sm-12"> 
        { this.state.showTopicDescription ? 
         // pass the selected topic ID assuming this component will 
         // then re-render based on the ID that it's passed 
         <IndividualTopicPages 
          selectedTopic={this.state.selectedTopicID} 
          closeTopicCallback={this.closeTopicCallback} // closing the topic 
         /> 
        : null } 
       </div> 
      </div> 
     ); 
    } 
}); 

// this doesn't really need to be a var in this scope 
// var selected_topic_no; 

var IndividualTopic = React.createClass({ 
    onClick: function(event) { 
     // assuming you're using ES6, declare this as a let as it's only 
     // ever used here, if not just a local var will work fine 
     let selectedTopicID = this.props.topicID - 1; 
     // call the callback that's passes as a prop, send the topic ID 
     // as a parameter 
     this.props.topicSelectionCallback(event, selectedTopicID); 
    }, 

    render: function() { 
     return (
      <div> 
       <div className="col-sm-2"> 
        <div onClick={this.onClick} className="single-topic" data-topic-id={this.props.topicID}> 
         {this.props.label} {this.props.topicID} // render out the label and topicID here 
        </div> 
       </div> 
      </div> 
     ); 
    } 
}); 
+0

我得到這個錯誤「Uncaught TypeError:this.props.topicSelectionCallback不是一個函數」 –

+0

這可能是許多事情。錯誤在哪裏被拋出?在IndividualTopic或TopicsList中?如果您將代碼發佈到CodePen上,我們可以嘗試解決問題的底部。 – jolyonruss

相關問題