title: reactjs - expose react component methods outside react tree
body: <p><strong>Question:</strong></p>
  
  <p>How can I expose a react component's methods to other places? </p>
  
  <p>For example, I want to call React-Router's this.context.router.push(location) from an element outside of React. </p>
  
  <p>Perhaps I could add a React component's method to the window object so it can be called from any generic DOM event listener or even the console?</p>
  
  <p><strong>Background/Use Case:</strong></p>
  
  <p>I want to use jQuery DataTables in my React app because it provides many plugins and config which are still unavailable in the React ecosystem.</p>
  
  <p>I started from an existing React datatable component (implementation below). </p>
  
  <p>The original provides nice option to pass a render function which can, for example, render other React components inside the cells. Below, the cells in the 'Product Name' column are rendered as React-Router &lt; Link /> components.</p>
  
  <pre><code>    const data =  [
          { 
            product_id: '5001', 
            product_price: '$5', 
            product_name: 'Apple'
           },
           ...
        ];
  
      const renderUrl =
        (val, row) =&gt; {
          return (&lt;Link to={`/product/${row.product_id}`}&gt;{row.product_name}&lt;/Link&gt;);
        };
  
      const columns = [
          { title: 'Product Name', prop: 'product_id', render: renderUrl },
          { title: 'Price', prop: 'product_price' },
        ];
  
      &lt;DataTable
        className="datatable-container"
        columns={columns}
        initialData={data}
      /&gt;
  </code></pre>
  
  <p>What I've done to modify the existing component involves hiding the table from React's DOM diffing algorithm, since it would otherwise break when jQuery DataTables modifies the DOM.</p>
  
  <ol>
  <li>Move the component's <em>render()</em> code into a custom method <em>getDtMarkup()</em> on the class (outside of the react lifecycle).</li>
  <li><p><em>render()</em> now outputs an empty div with a <em>ref</em> and <em>id</em></p>
  
  <pre><code>  render() {
      return (
        &lt;div&gt;
          &lt;div ref="dtContainer" id="dtContainer"&gt;&lt;/div&gt;
        &lt;/div&gt;
      );
    }
  </code></pre></li>
  <li><p>componentDidMount uses ReactDomServer.renderToStaticMarkup to turn a React component into plain, non-react markup and appends this to the #dtContainer div from render(). Finally jQuery DataTables initializes the rendered table html as a fancy 'jQuery DataTable'.</p>
  
  <pre><code>componentDidMount() {
  
    let table = this.getDTMarkup();
    let dtContainer = this.refs.dtContainer;
    let renderedTable = ReactDOMServer.renderToStaticMarkup(table, dtContainer);
  
    $('#dtContainer').append(renderedTable);
  
    let jqueryTable = $('#dt'); // hard coded in getDTMarkup() for now
  
    // Turn html table into a jQuery DataTable with desired config options
    jqueryTable.DataTable({
      dom: '&lt;"html5buttons"B&gt;lTfgitp',
      buttons: [
        'copy', 'csv', 'excel', 'pdf', 'print'
      ],
      "pagingType": 'numbers',
      "bAutoWidth": false,
      "bDestroy": true,
      "fnDrawCallback": function() {
        console.log('datatables fnDrawCallback');
      }
    });
  }
  </code></pre></li>
  </ol>
  
  <blockquote>
    <p>src <a href="https://github.com/alecperkey/react-jquery-datatables/blob/master/src/Table.js#L89-L111" rel="nofollow">https://github.com/alecperkey/react-jquery-datatables/blob/master/src/Table.js#L89-L111</a></p>
  </blockquote>
  
  <p>The limitation that has me asking this question is that I am now unable to use React components such as &lt; Link /> inside of this static, non-React markup. I am using &lt; a href=""> for now, but this will reload the page, which is slower and causes the white flash of the browser.</p>