jquery - reactjs - expose react component methods outside react tree -


question:

how can expose react component's methods other places?

for example, want call react-router's this.context.router.push(location) element outside of react.

perhaps add react component's method window object can called generic dom event listener or console?

background/use case:

i want use jquery datatables in react app because provides many plugins , config still unavailable in react ecosystem.

i started existing react datatable component (implementation below).

the original provides nice option pass render function can, example, render other react components inside cells. below, cells in 'product name' column rendered react-router < link /> components.

    const data =  [         {            product_id: '5001',            product_price: '$5',            product_name: 'apple'          },          ...       ];      const renderurl =       (val, row) => {         return (<link to={`/product/${row.product_id}`}>{row.product_name}</link>);       };      const columns = [         { title: 'product name', prop: 'product_id', render: renderurl },         { title: 'price', prop: 'product_price' },       ];      <datatable       classname="datatable-container"       columns={columns}       initialdata={data}     /> 

what i've done modify existing component involves hiding table react's dom diffing algorithm, since otherwise break when jquery datatables modifies dom.

  1. move component's render() code custom method getdtmarkup() on class (outside of react lifecycle).
  2. render() outputs empty div ref , id

      render() {     return (       <div>         <div ref="dtcontainer" id="dtcontainer"></div>       </div>     );   } 
  3. componentdidmount uses reactdomserver.rendertostaticmarkup turn react component plain, non-react markup , appends #dtcontainer div render(). jquery datatables initializes rendered table html fancy 'jquery datatable'.

    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()    // turn html table jquery datatable desired config options   jquerytable.datatable({     dom: '<"html5buttons"b>ltfgitp',     buttons: [       'copy', 'csv', 'excel', 'pdf', 'print'     ],     "pagingtype": 'numbers',     "bautowidth": false,     "bdestroy": true,     "fndrawcallback": function() {       console.log('datatables fndrawcallback');     }   }); } 

src https://github.com/alecperkey/react-jquery-datatables/blob/master/src/table.js#l89-l111

the limitation has me asking question unable use react components such < link /> inside of static, non-react markup. using < href=""> now, reload page, slower , causes white flash of browser.

there several ways wire react components "outer application"

you can pass methods props component like:

const foo = function(){   alert(1) }  class helloworldcomponent extends react.component {   render() {     return (             <h1 onclick={(e) => this.props.cb()}>hello {this.props.name}</h1>           );   } }  react.render(   <helloworldcomponent cb={foo} name="joe schmoe"/>,   document.getelementbyid('react_example') ); 

http://jsbin.com/zujebirusa/1/edit?js,output

using global methods attached window. keep in mind that's hard maintain pollute global namespace.

window.foo = function(){   alert(1) }  class helloworldcomponent extends react.component {   render() {     return (             <h1 onclick={(e) => window.foo()}>hello {this.props.name}</h1>           );   } }  react.render(   <helloworldcomponent name="joe schmoe"/>,   document.getelementbyid('react_example') ); 

http://jsbin.com/woyokasano/1/edit?js,output

using es6 module system in order keep codebase tidy separate scopes

//methods.js  export function foo() {     alert(1) }  import {foo} './methods'; class helloworldcomponent extends react.component {   render() {     return (             <h1 onclick={(e) => foo()}>hello {this.props.name}</h1>           );   } }  react.render(   <helloworldcomponent name="joe schmoe"/>,   document.getelementbyid('react_example') ); 

Comments

Popular posts from this blog

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

wordpress - (T_ENDFOREACH) php error -

Using django-mptt to get only the categories that have items -