AbdulrahmanDev
AbdulrahmanDev

Reputation: 45

How can I return back values to parent component?

I am using a component inside a component. It is well know that how to send data to child component. But how can I return back values from the child component to the parent component? I read componentDidMount, componentWillMount, but I am still confused in understanding how can I return back values to parent component from child component.

In my following code, please help me to return back a value from the child Catalog.jsx to the Parent component AppWrapper.jsx. Such that, I want to to return back from the function ProductButtonClicked at Catalog.jsx the state value number_ofItems to AppWrapper.jsx state value itemsAdded

Note: At AppWrapper.jsx, there is

Here is my Catalog.jsx file

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;

And here is my 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;

Upvotes: 0

Views: 568

Answers (1)

J3Y
J3Y

Reputation: 1853

In React, you will usually pass data back to the parent by using callbacks as props. Something like this:

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});
    }
});

The child takes the callback onIncrementCount, and the parent passes in its own local function as the callback. The child can then trigger this callback.

Edit: In regards to your new information, in your ProductButtonClicked function, you need to store the number_ofItems in a local variable, then assign setState at the end of your function. So instead of calling setState, assign it in a similar fashion to this:

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);

However, in your parent function, you need to pass in the incrementCount function as props to the Catalog when it's rendered.

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
    }
})

Upvotes: 1

Related Questions