Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery reactjs-在react树外部公开react组件方法_Jquery_Reactjs_React Router_React Dom - Fatal编程技术网

Jquery reactjs-在react树外部公开react组件方法

Jquery reactjs-在react树外部公开react组件方法,jquery,reactjs,react-router,react-dom,Jquery,Reactjs,React Router,React Dom,问题: 如何将react组件的方法公开给其他地方 例如,我想从React外部的元素调用React路由器的this.context.Router.push(location) 也许我可以将React组件的方法添加到窗口对象中,以便可以从任何通用DOM事件侦听器甚至控制台调用它 背景/用例: 我想在我的React应用程序中使用jQuery DataTables,因为它提供了许多插件和配置,这些插件和配置在React生态系统中仍然不可用 我从现有的React datatable组件(下面的实现)开始

问题:

如何将react组件的方法公开给其他地方

例如,我想从React外部的元素调用React路由器的this.context.Router.push(location)

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

背景/用例:

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

我从现有的React datatable组件(下面的实现)开始

原始版本提供了一个很好的选项来传递一个渲染函数,例如,该函数可以渲染单元内的其他React组件。下面,“产品名称”列中的单元格显示为React Router组件

    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}
    />
const数据=[
{ 
产品编号:“5001”,
产品价格:‘$5’,
产品名称:“苹果”
},
...
];
常量渲染器=
(val,世界其他地区)=>{
返回({row.product_name});
};
常量列=[
{title:'Product Name',prop:'Product_id',render:renderUrl},
{标题:“价格”,道具:“产品价格”},
];
我所做的修改现有组件的工作涉及到对React的DOM扩散算法隐藏表,因为如果jQuery DataTables修改DOM,它将被破坏

  • 将组件的render()代码移动到类上的自定义方法getDtMarkup()中(在react生命周期之外)
  • render()现在输出一个带有ref和id的空div

    render(){
    返回(
    );
    }
    
  • componentDidMount使用ReactDomServer.renderToStaticMarkup将React组件转换为普通的非React标记,并将其附加到来自render()的#dtContainer div中。最后,jquerydatatables将呈现的表html初始化为一个奇特的“jquerydatatable”

    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');
        }
      });
    }
    
    componentDidMount(){
    让table=this.getDTMarkup();
    设dtContainer=this.refs.dtContainer;
    让renderedTable=ReactDOMServer.renderToStaticMarkup(表,dtContainer);
    $('#dtContainer').append(renderedTable);
    现在让jqueryTable=$('#dt');//在getDTMarkup()中硬编码
    //将html表转换为具有所需配置选项的jQuery数据表
    jqueryTable.DataTable({
    dom:“lTfgitp”,
    按钮:[
    “复制”、“csv”、“excel”、“pdf”、“打印”
    ],
    “pagingType”:“数字”,
    “bAutoWidth”:假,
    是的,
    “fnDrawCallback”:函数(){
    log('datatables fnDrawCallback');
    }
    });
    }
    
  • src


    我问这个问题的局限性是,我现在无法在这个静态、非React标记中使用React组件,例如。我现在正在使用但这会重新加载页面,速度较慢,并导致浏览器出现白色闪烁。

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

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

    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')
    );
    
    const foo=function(){
    警报(1)
    }
    类HelloWorldComponent扩展了React.Component{
    render(){
    报税表(
    this.props.cb()}>你好{this.props.name}
    );
    }
    }
    反应(
    ,
    document.getElementById('react\u example')
    );
    

    使用附加到窗口的全局方法。请记住,这很难维护,因为它会污染全局名称空间

    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')
    );
    
    window.foo=function(){
    警报(1)
    }
    类HelloWorldComponent扩展了React.Component{
    render(){
    报税表(
    window.foo()}>你好{this.props.name}
    );
    }
    }
    反应(
    ,
    document.getElementById('react\u example')
    );
    

    使用ES6模块系统以保持代码库整洁,并使用单独的作用域

    //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')
    );
    
    //methods.js
    导出函数foo(){
    警报(1)
    }
    从“./methods”导入{foo};
    类HelloWorldComponent扩展了React.Component{
    render(){
    报税表(
    foo()}>你好{this.props.name}
    );
    }
    }
    反应(
    ,
    document.getElementById('react\u example')
    );
    
    这就是我如何将react组件中的方法公开到“全局”范围或react应用程序之外的方法。 我真的不知道你的具体情况,但这可能对你有用。此外,我使用钩子,但这也适用于遗留的生命周期方法

    假设这是我的组件。它只是呈现一个由状态管理的数字

    const MyCount=({getMethods})=>{
    const[state,setState]=useState(1);
    useffect(()=>{
    getMethods({setState});
    }, []);
    返回{state};
    }
    
    你看,
    getMethods
    是这项工作的关键支柱。该函数将在安装组件时执行,并提供我需要作为参数公开的方法。在这种情况下,使用
    setState
    方法

    现在让我们假设我在react外有一个按钮,我想用它来触发该方法

    //我想将方法存储在此变量中
    让全球方法;
    //渲染react组件时,我会传递属性“getMethods”
    //这将分配返回值
    render(globalMethods=methods}/>,$someEl);
    //现在我可以在外面用了
    $(“#我的按钮”)。单击(()=>{
    全局方法设置状态(2);
    })
    

    希望这能有所帮助。或者你甚至不再需要它,因为它已经晚了3.9年

    您已经向我展示了如何向React组件添加方法。这不是我想问的。我试图做的是将React组件的现有方法绑定到全局上下文(如window)或非React DOM元素。。。因此,可以从通用DOM事件侦听器甚至控制台调用它。例如,如何将React路由器功能this.context.Router.push绑定到w
    //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')
    );