title: React: How to render a parent component from child component?
body: <p>I've been tasked with building out a project for a client that entails one parent component wrapping three sub components. Specifically the parent component renders the sub components into being according to the following manner:</p>
  
  <p>PARENT = TOP + MIDDLE + BOTTOM</p>
  
  <p>The PARENT component represents one of a group of items. </p>
  
  <p>In the TOP component there is a menu button that displays a list of all items in the group with the intent that should the user click on one of those links, the selected item will display (PARENT will "re-render to" the new item - there's logic in PARENT that will cause the selected, second, item to appear rather than the first).</p>
  
  <p>I'm speaking loosely here and can supply code if what I'm talking about it isn't clear (I think it should be).</p>
  
  <p>The primary issue I'm having is trying to "re-render" the parent component from one of the child components. Essentially, there's a menu button that appears displaying a list of related items. Clicking on one of those items should re-render the parent component but this time displaying the selected item.  I don't know of a way to do this however and was hoping to get some advice or help. I've spent the morning researching the topic and trying a few suggested ways to no avail.</p>
  
  <p>Perhaps the approach I've taken so far is not the best to accomplish this sort of task.  In any event, any assistance would be very helpful.  Thank you!</p>
  
  <hr>
  
  <p>EDIT: NOW WORKING</p>
  
  <p>EDIT #2: Since this has gotten quite a few views I just wanted to clarify that this was a proof of concept and also very simplified prototype/early version (no fancy transpilation, etc. - a can this idea work sort of thing ... since we weren't sure at the time). It's been a while since I worked on anything like that but I really appreciate all the help for such a confusing question that I asked and what was at that time a very interesting and challenging task.</p>
  
  <pre><code> import React from 'react';
  
  import CardHeader from 'components/CardHeader';
  import CardContent from 'components/CardContent';
  import CardFooter from 'components/CardFooter';
  
  module.exports = React.createClass({
  
    getInitialState: function () {
      return {
        fullData: '',
  
        //Core Card
        userId: '',
        cardStack: '',
        cardId: '',
  
        //Load Card
        loadCard: '1',
  
        //Optional Fields
        name: '',
        type: '',
        headline: '',
        subtitle: '',
        ctext: '',
        imageUrl: '',
        price: '',
        mapCoordinates: '',
        logoUrl: '',
        order: '',
        email: '',
        sponsorUrl: '',
        pollId: '',
        socialButton: ''
      };
    }
    ,
  
    componentWillMount: function () {
  
      //fetches cardStack and card API JSON
      /** JSON Structure:
       [
       cardStack: ...,
       cards: ...
       ]
       **/
  
      var fetch = function (userId, cardStackId) {
  
        //AJAX
  
        var json = {
          'cardStack': {'id': '1', 'name': 'Test Card Stack', 'userID': 'O1AB0001'},
          'cards': [{
            'id': '1',
            'name': 'Test Card 1',
            'cardStack': '1',
            'meta': 'meta_note',
            'socialButton': 'twitter',
            'sponsorUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
            'order': 1,
            'logoUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
            'product': {
              'headline': 'Headline Test',
              'subtitle': 'Subtitle Test',
              'ctext': 'Hello!!!!',
              'imageUrl': 'http://the-mpas.com/wp-content/uploads/2012/04/Image-pic-54-copy.jpg',
              'price': '20.00'
            }
          }, {
            'id': '2',
            'name': 'Test Card 2',
            'cardStack': '1',
            'meta': 'meta_note',
            'socialButton': 'twitter',
            'sponsorUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
            'order': 2,
            'logoUrl': 'https://iwantmyname.com/images/logo-url-shortener-droplr.png',
            'product': {
              'headline': 'Headline Test 2',
              'subtitle': 'Subtitle Test 2',
              'ctext': 'Hello 2!!!!',
              'imageUrl': 'http://the-mpas.com/wp-content/uploads/2012/04/Image-pic-54-copy.jpg',
              'price': '30.00'
            }
          }]
        };
  
        return json;
      };
  
      var that = this;
  
      var getCard = function (cardArray, cardOrder) {
        var card;
        for (var key in cardArray) {
          if (cardArray[key].order == cardOrder) {
            card = cardArray[key];
          }
        }
  
        if ('product' in card) {
          that.setState({
            type: 'product',
            headline: card.product.headline,
            subtitle: card.product.subtitle,
            ctext: card.product.ctext,
            imageUrl: card.product.imageUrl,
            price: card.product.price
          })
        }
        if ('article' in card) {
          that.setState({
            type: 'article',
            headline: card.article.headline,
            ctext: card.article.ctext
          })
        }
  
        if ('map' in card) {
          that.setState({
            type: 'map',
            mapCoordinates: card.map.mapCoordinates
          })
        }
  
        if ('relatedvideo' in card) {
          that.setState({
            type: 'relatedvideo',
            headline: card.relatedvideo.headline,
            ctext: card.relatedvideo.ctext,
            imageUrl: card.relatedvideo.imageUrl
          })
        }
  
        if ('poll' in card) {
          that.setState({
            type: 'poll',
            headline: card.poll.headline,
            subtitle: card.poll.subtitle,
            pollId: card.poll.pollId
          })
        }
  
        if ('imagegallery' in card) {
          that.setState({
            type: 'imagegallery',
            headline: card.imagegallery.headline,
            ctext: card.imagegallery.ctext,
            imageUrl: card.imagegallery.imageUrl
          })
        }
  
        if ('profile' in card) {
          that.setState({
            type: 'profile',
            headline: card.profile.headline,
            ctext: card.profile.ctext,
            imageUrl: card.profile.imageUrl
          })
        }
  
        if ('newsletter' in card) {
          that.setState({
            type: 'newsletter',
            email: card.newsletter.email
          })
        }
        return card;
      };
  
  //Entry Point HERE
      var userId = 'O1AB0001', cardStackId = 1;
      var json = fetch(userId, cardStackId);
      var myCard = getCard(json.cards, this.state.loadCard);
  
  //Set core data
      this.setState({
  
        //fulldata
        fullData: json,
  
        //card stack
        userId: json.cardStack.name,
        cardStack: json.cardStack.id,
  
        //card
        cardId: myCard.id,
        socialButton: myCard.socialButton,
        order: myCard.order,
        sponsorUrl: myCard.sponsorUrl,
        logoUrl: myCard.logoUrl,
        meta: myCard.meta,
        name: myCard.name
      });
    },
  
    setNew: function (nextState) {
  
      var nsFullData = nextState.fullData;
      var nsCards = nsFullData.cards;
      var nsCardStack = nsFullData.cardStack;
  
      var that = this;
      var getCard = function (cardArray, cardOrder) {
        var card;
        for (var key in cardArray) {
          if (cardArray[key].order == cardOrder) {
            card = cardArray[key];
          }
        }
  
        if ('product' in card) {
          that.setState({
            type: 'product',
            headline: card.product.headline,
            subtitle: card.product.subtitle,
            ctext: card.product.ctext,
            imageUrl: card.product.imageUrl,
            price: card.product.price
          })
        }
        if ('article' in card) {
          that.setState({
            type: 'article',
            headline: card.article.headline,
            ctext: card.article.ctext
          })
        }
  
        if ('map' in card) {
          that.setState({
            type: 'map',
            mapCoordinates: card.map.mapCoordinates
          })
        }
  
        if ('relatedvideo' in card) {
          that.setState({
            type: 'relatedvideo',
            headline: card.relatedvideo.headline,
            ctext: card.relatedvideo.ctext,
            imageUrl: card.relatedvideo.imageUrl
          })
        }
  
        if ('poll' in card) {
          that.setState({
            type: 'poll',
            headline: card.poll.headline,
            subtitle: card.poll.subtitle,
            pollId: card.poll.pollId
          })
        }
  
        if ('imagegallery' in card) {
          that.setState({
            type: 'imagegallery',
            headline: card.imagegallery.headline,
            ctext: card.imagegallery.ctext,
            imageUrl: card.imagegallery.imageUrl
          })
        }
  
        if ('profile' in card) {
          that.setState({
            type: 'profile',
            headline: card.profile.headline,
            ctext: card.profile.ctext,
            imageUrl: card.profile.imageUrl
          })
        }
  
        if ('newsletter' in card) {
          that.setState({
            type: 'newsletter',
            email: card.newsletter.email
          })
        }
        return card;
      };
  
      var myCard = getCard(nsCards, this.state.loadCard);
  
      this.setState({
  
        //fulldata
        fullData: nsFullData,
  
        //card stack
        userId: nsCardStack.name,
        cardStack: nsCardStack.id,
  
        //card
        cardId: myCard.id,
        socialButton: myCard.socialButton,
        order: myCard.order,
        sponsorUrl: myCard.sponsorUrl,
        logoUrl: myCard.logoUrl,
        meta: myCard.meta,
        name: myCard.name
      });
    },
  
    componentWillUpdate: function (nextProps, nextState) {
      if (nextState.loadCard !== this.state.loadCard) {
        this.setNew(nextState);
      }
    },
  
    render: function () {
  
      return (
        &lt;div className='sg-cardBase'&gt;
          &lt;div className='sg-cardHeaderSection'&gt;
            &lt;CardHeader setLoadCard={i =&gt; this.setState({loadCard: i})} data={this.state}/&gt;
          &lt;/div&gt;
          &lt;div className='sg-cardContentSection'&gt;
            &lt;CardContent data={this.state}/&gt;
          &lt;/div&gt;
          &lt;div className='sg-cardFooterSection'&gt;
            &lt;CardFooter data={this.state}/&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      );
    }
  });
  </code></pre>