2015-10-19 100 views
0

我正在使用组件内的组件。知道如何将数据发送给子组件。但是,我怎样才能从子组件返回值到父组件?我读componentDidMount,componentWillMount,但我仍然困惑于理解如何返回值从父组件的父组件。如何将值返回给父组件?

在我的下面的代码中,请帮助我将一个值从子Catalog.jsx返回给父组件AppWrapper.jsx。这样,我想从功能ProductButtonClicked在Catalog.jsx返回回状态值number_ofItems到AppWrapper.jsx 状态值itemsAdded

注:在AppWrapper.jsx,有

这里是我Catalog.jsx文件

var React = require('react'); 
 
var Parse = require('parse').Parse; 
 
var ParseReact = require('parse-react'); 
 
var cookie = require('react-cookie'); 
 

 
var Catalog = React.createClass({ 
 
mixins: [ParseReact.Mixin], 
 

 
getInitialState: function() { 
 
    return { 
 
    // if the cookie is there, It will return the cookie value which I saved as 'true' word. 
 
    FTWVeyCc4o: cookie.load('RahlTradingProductID-FTWVeyCc4o'), 
 
    aJ3DoJp352: cookie.load('RahlTradingProductID-aJ3DoJp352'), 
 
    dgeRhSG21U: cookie.load('RahlTradingProductID-dgeRhSG21U'), 
 
    number_ofItems: 0 
 
    }; 
 
}, 
 

 
componentDidMount: function() { 
 
this.noOfItemsAdded(); 
 
}, 
 

 

 
//Observe Function - a newly proposed function for prarse react integration 
 
observe: function() { 
 
    //declare any variable you need here. 
 

 
    return { 
 
    product: (new Parse.Query('product')) 
 
       .ascending('createdAt') 
 
    }; 
 
}, 
 

 
    //Render 
 
    render: function() { 
 

 
    var content = (
 
     <div> 
 
     no product 
 
     </div> 
 
    ); 
 

 
    if(this.data.product.length){ 
 
     var content = (
 
     <div> 
 
      { // Products are listed in this 
 
           this.data.product.map(function(p) { 
 

 
           return (
 
           // <div>man</div> 
 

 
            //From Design 
 
            <div className="col-md-4"> 
 

 
             <div className="item text-center"> 
 

 
              <div className="photo"> 
 

 
               <img src={ p.productImgUrl } /> 
 
               <br /><br /> 
 
               <h5>{p.name} <br /> {p.size}</h5> 
 
              </div> 
 
             </div> 
 
              <div className="action"> 
 
               <button 
 
               type="button" 
 
               className={"btn btn-" 
 
                + (
 
                 (this.state.FTWVeyCc4o && (p.objectId == "FTWVeyCc4o")) || (this.state.aJ3DoJp352 && (p.objectId == "aJ3DoJp352")) || (this.state.dgeRhSG21U && (p.objectId == "dgeRhSG21U")) ? 'warning' : 'primary' 
 
                )} 
 

 
               onClick={this.ProductButtonClicked.bind(this, p)} 
 
               > 
 
               {(
 
                (this.state.FTWVeyCc4o && (p.objectId == "FTWVeyCc4o")) || (this.state.aJ3DoJp352 && (p.objectId == "aJ3DoJp352")) || (this.state.dgeRhSG21U && (p.objectId == "dgeRhSG21U")) ? 'Remove' : 'Add' 
 
               )} 
 
               </button> 
 
               
 
              </div> 
 

 

 
            </div> 
 
           ); 
 
          }, this)} 
 

 

 
     </div> 
 

 
    ); 
 

 
    } 
 
    else{ 
 
     var content = (<div> 
 

 
     </div>); 
 
     } 
 
    return <div>{content}</div>; 
 
    }, 
 

 
    ProductButtonClicked:function(obj){ 
 
    //alert(this.incrementCount()) 
 
    // a = this.state.bind(obj.objectId); 
 
    // if(a == "" ) 
 
    if(this.getCookiefunc('RahlTradingProductID-' + obj.objectId) == "") 
 
     { 
 
     //create the cookie 
 
     document.cookie="RahlTradingProductID-" + obj.objectId + "=true; expires=Thu, 18 Dec 2017 12:00:00 UTC; path=/"; 
 
      //update state 
 
      if(obj.objectId == "FTWVeyCc4o") 
 
      { 
 
       this.setState({FTWVeyCc4o:true}); 
 
       this.setState({number_ofItems: this.state.number_ofItems + 1}); 
 

 

 
      } 
 
      else if(obj.objectId == "aJ3DoJp352") 
 
      { 
 
       this.setState({aJ3DoJp352:true}); 
 
       this.setState({number_ofItems: this.state.number_ofItems + 1}); 
 
      } 
 
      else if(obj.objectId == "dgeRhSG21U") 
 
      { 
 
       this.setState({dgeRhSG21U:true}); 
 
       this.setState({number_ofItems: this.state.number_ofItems + 1}); 
 
      } 
 
     } 
 
    else 
 
     {//alert("Delete Cookie") 
 
     //delete the cookie 
 
     document.cookie="RahlTradingProductID-" + obj.objectId + "=; expires=Thu, 18 Dec 2000 12:00:00 UTC; path=/"; 
 

 
     if(obj.objectId == "FTWVeyCc4o") 
 
      { 
 
      this.setState({FTWVeyCc4o:false}); 
 
      this.setState({number_ofItems: this.state.number_ofItems - 1}); 
 
      } 
 
     else if(obj.objectId == "aJ3DoJp352") 
 
      { 
 
      this.setState({aJ3DoJp352:false}); 
 
      this.setState({number_ofItems: this.state.number_ofItems - 1}); 
 
      } 
 
     else if(obj.objectId == "dgeRhSG21U") 
 
      { 
 
      this.setState({dgeRhSG21U:false}); 
 
      this.setState({number_ofItems: this.state.number_ofItems - 1}); 
 
      } 
 

 
     } 
 

 
    }, 
 

 
    noOfItemsAdded:function(){ 
 

 
    counter= 0; 
 
    if(this.state.FTWVeyCc4o) 
 
    counter = counter +1; 
 
     if(this.state.aJ3DoJp352) 
 
     counter = counter +1; 
 
     if(this.state.dgeRhSG21U) 
 
     counter = counter +1; 
 
     this.setState({number_ofItems: counter}); 
 
     //alert(counter); 
 
    }, 
 

 

 
    getCookiefunc:function(cname){ 
 
    var name = cname + "="; 
 
    var ca = document.cookie.split(';'); 
 
    for(var i=0; i < ca.length; i++) { 
 
     var c = ca[i]; 
 
     while (c.charAt(0)==' ') c = c.substring(1); 
 
     if (c.indexOf(name) == 0) return c.substring(name.length,c.length); 
 
    } 
 
    return ""; 
 
    } 
 

 
}); 
 

 
module.exports = Catalog;

这里是我的AppWrapper.jsx

var React = require('react'); 
 

 
var Catalog = require('./Catalog'); 
 
// var cart = require('./cart'); 
 

 

 
var contents = [ 
 
    <Catalog onIncrementCount={this.onIncrementCount}/> 
 
    // ,<cart /> 
 
]; 
 

 

 

 
var AppWrapper = React.createClass({ 
 
    getInitialState: function() { 
 
    return { 
 
     currentTab: 0, 
 
     count: 0 
 
    }; 
 
    }, 
 

 
    onIncrementCount: function() { 
 
     this.setState({count: this.state.count + 1}); 
 
alert(this.state.count) 
 
    }, 
 

 
    render: function() { 
 
    return (
 
<div> 
 
     <div className="site-wrapper"> 
 

 
     <div className="site-wrapper-inner"> 
 

 
      <div className="cover-container"> 
 

 

 

 
       <div className="masthead clearfix"> 
 
        <div className="inner"> 
 
         <h3 className="masthead-brand"> 
 
          <img src="images/naleczowianka-logo.png" /> 
 
         </h3> 
 

 
         <nav> 
 
          <ul className="nav masthead-nav"> 
 
           <li className="active"><a href="#" >English <span className="glyphicon glyphicon-menu-down"></span></a></li> 
 
           <li><a href="#"><span className="glyphicon glyphicon-log-in"></span>&nbsp; Login</a></li> 
 

 
          </ul> 
 
        </nav> 
 
        </div> 
 
       </div> 
 

 
       <br /> 
 

 
       <div className="inner cover"> 
 

 
        <header className="row"> 
 
         <div className="col-md-12"> 
 

 
          <div className="row"> 
 
           <div className="col-md-4 col-xs-4"><h4 className="active">Choose Product</h4></div> 
 

 
           <div className="col-md-4 col-xs-4"><h4> 
 
           <a href="#"> 
 
            <span className="glyphicon glyphicon-shopping-cart"> </span> 
 
            &nbsp; 
 
           </a> 
 
           <a href="http://www.google.com" className="NavLinks" >Shopping Cart ({this.state.count}) </a> 
 
           </h4></div> 
 
           <div className="col-md-4 col-xs-4"><h4>Order</h4></div> 
 
          </div> 
 

 

 
          <br /> 
 

 
          <div className="progress"> 
 
           <div className="progress-bar progress-bar-striped active width-15" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" > 
 
            <span className="sr-only">15% Complete</span> 
 
           </div> 
 
          </div> 
 

 
         </div> 
 
        </header> 
 

 
        <br /> 
 

 
        <main className="row box"> 
 

 
         <div className="col-md-12"> 
 

 

 
         <div className="row"> 
 

 

 
         <div > 
 
         {contents[this.state.currentTab] } 
 
         </div> 
 

 

 
         <br /> 
 

 
         <div className="row"> 
 

 
          <div className="col-md-6"> 
 
           <h4>Still Waters</h4> 
 
           <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> 
 
          </div> 
 

 
          <div className="col-md-6"> 
 
           <h4>Sparkling Waters</h4> 
 
           <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> 
 
          </div> 
 
         </div> 
 

 
         </div> 
 

 
         </div> 
 
         </main> 
 

 
         <div className="mastfoot"> 
 
         <div className="inner row"> 
 

 
         <div className="col-md-4 col-xs-4"> 
 
         <a href="">Rahl Trading</a> 
 
         </div> 
 

 
         <div className="col-md-4 col-xs-4"> 
 
         <a href="">Frequently Asked Questions</a> 
 
         </div> 
 

 
         <div className="col-md-4 col-xs-4"> 
 
         <a href="">Privacy</a> 
 
         </div> 
 

 
         </div> 
 
         </div> 
 

 
         </div> 
 

 
         </div> 
 

 
         </div> 
 
         </div> 
 
         </div> 
 

 
    
 

 
    ); 
 
    }, 
 

 
    selectTab: function(tab) { 
 
    this.setState({ currentTab: tab }); 
 
    // this.props.tabChanged(tab); 
 
    } 
 
}); 
 

 
module.exports = AppWrapper;

回答

1

在反应,你通常会使用回调作为道具将数据传递回父。事情是这样的:

var Child = React.createClass({ 
    getDefaultProps: function() { 
     return { 
      onIncrementCount: null 
     }; 
    }, 

    render: function() { 
     return <button onClick={this.incrementCount}>Increment</button>; 
    }, 

    incrementCount: function() { 
     // Some data you want to pass externally 
     var data = [1,2,3]; 
     this.props.onIncrementCount.call(this, data); 
    } 
}); 

var Parent = React.createClass({ 
    render: function() { 
     return (
      <div> 
       <Child onIncrementCount={this.onIncrementCount} /> 
       <div>Count is {this.state.count}</div> 
      </div> 
     ); 
    }, 

    getInitialState: function() { 
     return { 
      count: 0 
     }; 
    }, 

    onIncrementCount: function() { 
     this.setState({count: this.state.count + 1}); 
    } 
}); 

孩子需要回调onIncrementCount,和家长通过在自己的本地函数作为回调。然后孩子可以触发这个回调。

编辑: 在问候你的新的信息,在你的ProductButtonClicked功能,您需要将number_ofItems存储在一个局部变量,然后在你的函数结束指定的setState。因此,而不是调用setState,以类似的方式分配给它这样的:

var number_ofItems; 
if(this.getCookiefunc('RahlTradingProductID-' + obj.objectId) == "") 
    // Your usual logic here, but set the local variable 
    number_ofItems = this.state.number_ofItems - 1; 
} 

// End of your function 
this.setState({number_ofItems: number_ofItems}); 

// Send the data to the parent 
this.props.incrementCount(number_ofItems); 

然而,在父功能,你需要时,它呈现在incrementCount函数传递作为道具目录。

var Parent = React.createClass({ 
    render: function() { 
     return <Catalog incrementCount={this.incrementCount} />; 
    }, 

    incrementCount: function(newCount) { 
     // Finally you can use your newCount here, which was from the child 
    } 
}) 
+0

太棒了!让我试试吧.... – AbdulrahmanDev

+0

我试过了,它在我的情况下不起作用,因为我使用了“Tabs”。你能帮忙吗?我把它放在JSFiddle中https://jsfiddle.net/6wjw9z1y/ – AbdulrahmanDev

+0

现在好了,我对你的用例有了更清晰的理解,你可以摆脱'incrementCount'方法,因为你已经知道你在哪里设置_tab_值(在你的'selectTab'方法中)。您可以在此处设置当前选项卡的状态,然后使用回叫在外部广播它。在'setState'之后,调用类似'this.props.tabChanged(tab)' – J3Y

相关问题