reactjs - 在反应树外暴露反应组分方法 [英] reactjs - expose react component methods outside react tree

查看:80
本文介绍了reactjs - 在反应树外暴露反应组分方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

如何将反应组件的方法暴露给其他地方?

How can I expose a react component's methods to other places?

例如,我想从React之外的元素调用React-Router的this.context.router.push(location)。

For example, I want to call React-Router's this.context.router.push(location) from an element outside of React.

也许我可以在窗口对象中添加一个React组件的方法,以便可以从任何通用DOM事件监听器甚至控制台调用它?

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?

背景/用例:

我想在我的React应用程序中使用jQuery DataTables,因为它提供了许多插件和配置在React生态系统中仍然不可用。

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.

我从一个现有的React数据表组件开始(下面的实现)。

I started from an existing React datatable component (implementation below).

原始提供了很好的选项来传递渲染函数,例如,可以渲染单元格内的其他React组件。下面,产品名称列中的单元格呈现为React-Router<链接/>组件。

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

我修改现有组件所做的工作包括将表隐藏在React的DOM diffing算法中,因为否则,当jQuery DataTables修改DOM时它会破坏。

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.


  1. 将组件的 render()代码移动到自定义中类的方法 getDtMarkup()(在反应生命周期之外)。

  2. render()现在输出一个空div带有 ref id

  1. Move the component's render() code into a custom method getDtMarkup() on the class (outside of the react lifecycle).
  2. render() now outputs an empty div with a ref and id

  render() {
    return (
      <div>
        <div ref="dtContainer" id="dtContainer"></div>
      </div>
    );
  }


  • componentDidMount使用ReactDomServer.renderToStaticMarkup将React组件转换为plain,非反应标记并将其附加到render()的#dtContainer div中。最后,jQuery DataTables将渲染的表格html初始化为花哨的jQuery DataTable。

  • 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'.

    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: '<"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

    让我问这个问题的限制是我现在无法使用React组件,例如<链接/>在此静态非React标记内。我正在使用< a href =>现在,但这会重新加载页面,这会慢一些并导致浏览器的白色闪烁。

    The limitation that has me asking this question is that I am now unable to use React components such as < Link /> inside of this static, non-React markup. I am using < a href=""> for now, but this will reload the page, which is slower and causes the white flash of the browser.

    推荐答案

    有几种方法可以将React组件与外部应用程序连接起来

    There are several ways to wire up React components with the "outer application"

    您可以将方法作为道具传递给组件,如:

    You can pass methods as props to your 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 to the window. Keep in mind that's hard to maintain as it will pollute the 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

    按顺序使用ES6模块系统使用单独的范围保持代码库整洁

    Using ES6 module system in order to keep your codebase tidy with separate scopes

    //methods.js
    
    export function foo() {
        alert(1)
    }
    
    import {foo} from './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')
    );
    

    这篇关于reactjs - 在反应树外暴露反应组分方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆