title: How to get a child component to control the parent in react?
body: <p>I'm building a Modal component and want to make sure that it would easily fit a variety of different possible modal designs.</p>
  
  <p>In my case it would have optional header, content and footer. I don't have an issue with this so far, the code looks like:</p>
  
  <pre><code>class ModalHeader extends React.Component {
      render () {
          const children = React.Children.map(this.props.children, _.identity);
          return (
              &lt;div className="modal-header"&gt;
                  {children}
              &lt;/div&gt;
          );
      }
  }
  
  class ModalFooter extends React.Component {
      render () {
          const children = React.Children.map(this.props.children, _.identity);
          return (
              &lt;div className="modal-footer"&gt;
                  {children}
              &lt;/div&gt;
          );
      }
  }
  
  class ModalContent extends React.Component {
      render () {
          const children = React.Children.map(this.props.children, _.identity);
          return (
              &lt;div className="modal-content"&gt;
                  {children}
              &lt;/div&gt;
          );
      }
  }
  
  class Modal extends React.Component {
      render () {
          var header, footer, content = null;
          React.Children.map(this.props.children, function(child){
              if (child.type === ModalHeader) {
                  header = child;
              }
              if (child.type === ModalFooter) {
                  footer = child;
              }
              if (child.type === ModalContent) {
                  content = child;
              }
          });
  
          return (
              &lt;div&gt;
                  {header}
                  {content}
                  {footer}
              &lt;/div&gt;
          );
      }
  }
  </code></pre>
  
  <p>Now comes the issue of closing the modal. I want it to be possible to close the modal from clicking an element that would be in any of the sub components, no matter, to the left or the right or anything and potentially nested deeply in the markup specific to that component.</p>
  
  <p>Having a component that would wrap a piece of markup be it an X, a close icon or a button, making sure that when that element is clicked, the whole modal is closed.</p>
  
  <pre><code>class ModalCloser extends React.Component {
      render () {
          const children = React.Children.map(this.props.children, _.identity);
          return (
              &lt;div onClick={this.close} className="modal-closer"&gt;
                  {children}
              &lt;/div&gt;
          );
      }
  
      close () {
          // no idea what goes here!!
      }
  }
  </code></pre>
  
  <p>There doesn't seem to be in React any easy way for a child component to communicate with the parent.</p>
  
  <p>I would be fine with passing a prop to that closer element that would be the callback function to close the main modal, but at the place where I would be defining the modal, I don't see any way that it would be available:</p>
  
  <pre><code>&lt;Modal&gt;
      &lt;ModalHeader&gt;
          &lt;div&gt;
              &lt;header&gt;
                  &lt;h1&gt;Title!!&lt;/h1&gt;
                  &lt;div class="float-right"&gt;
                      &lt;ModalCloser closeHandler={???}&gt;
                          X
                      &lt;/ModalCloser&gt;
                  &lt;/div&gt;
              &lt;/header&gt;
          &lt;/div&gt;
      &lt;/ModalHeader&gt;
      &lt;ModalContent&gt;
          ...
      &lt;/ModalContent&gt;
  &lt;/Modal&gt;
  </code></pre>
  
  <p>Alternatively, I see that I could recursively traverse all the descendants and maybe do something to all descendants of type <code>ModalCloser</code> but I also don't really see a way to do that available.</p>
  
  <p>What would be a good solution allowing to pass such a sub-component as a child or descendant to keep the layout flexibility while giving it the possibility to close the modal in such a case?</p>