问题:
如何将 React 组件的方法暴露给其他地方?
例如,我想从 React 之外的元素调用 React-Router 的 this.context.router.push(location)。
也许我可以将 React 组件的方法添加到窗口对象,以便可以从任何通用 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 差异算法隐藏表,否则当 jQuery DataTables 修改 DOM 时它会中断。
- 将组件的render()代码移动到类上的自定义方法getDtMarkup()中(在反应生命周期之外)。
render()现在输出一个带有ref和id的空 div
render() { return ( <div> <div ref="dtContainer" id="dtContainer"></div> </div> ); }
componentDidMount 使用 ReactDomServer.renderToStaticMarkup 将 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 />。我现在正在使用 <a href="">,但这会重新加载页面,速度较慢并导致浏览器出现白色闪烁。