gpt4 book ai didi

jquery - reactjs - 在 react 树之外公开 react 组件方法

转载 作者:行者123 更新时间:2023-12-03 13:51:42 24 4
gpt4 key购买 nike

问题:

如何将 React 组件的方法公开到其他地方?

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

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

背景/用例:

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

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

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

    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 时,它会中断。

  1. 将组件的 render() 代码移至类上的自定义方法 getDtMarkup() 中(在 React 生命周期之外)。
  2. render() 现在输出一个带有 refid

    的空 div
      render() {
    return (
    <div>
    <div ref="dtContainer" id="dtContainer"></div>
    </div>
    );
    }
  3. componentDidMount 使用 ReactDomServer.renderToStaticMarkup 将 React 组件转换为普通的非 React 标记,并将其附加到 render() 中的 #dtContainer div 中。最后,jQuery DataTables 将渲染的表格 html 初始化为一个奇特的“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 组件,例如 < Link/> 。我现在使用 ,但这会重新加载页面,速度较慢并导致浏览器出现白色闪烁。

最佳答案

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

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

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

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

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 模块系统以保持代码库整洁并具有不同的作用域

//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')
);

关于jquery - reactjs - 在 react 树之外公开 react 组件方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37758834/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com