React如何将子AgGrid组件的gridApi或刷新方法传递给父组件
最优解决方案:使用 forwardRef + useImperativeHandle
这是React官方提供的子组件向父组件暴露指定实例能力的标准方案,既可以灵活选择暴露封装好的业务方法,也可以按需暴露全量gridApi,完全覆盖你提到的两个需求,同时符合React组件设计规范。
步骤1:改造Grid子组件
import { useState, forwardRef, useImperativeHandle } from 'react' // 用forwardRef包裹组件,接收父组件传递的ref const Grid = forwardRef(({ tableData, columnData, ...props}, ref) => { const [gridApi, setGridApi] = useState(null); const [gridColumnApi, setGridColumnApi] = useState(null); const onGridReady = params => { setGridApi(params.api); setGridColumnApi(params.columnApi); } const refreshEntireGrid = () => { if(!gridApi) return; gridApi.setRowData(gridrowData); gridApi.refreshCells({force:true}); } const getSelectedRowData = (event) => { props.onselectedRows(event.api.getSelectedRows().length); } // 核心配置:指定要暴露给父组件的方法/属性 useImperativeHandle(ref, () => ({ // 可以只暴露封装好的业务方法,父组件无需关心内部实现 refreshEntireGrid, getSelectedRows: () => gridApi?.getSelectedRows() || [], // 如果有灵活操作需求,也可以直接暴露全量api gridApi, gridColumnApi }), [gridApi]) // 依赖项配置,gridApi更新时同步暴露的实例 return ( <div className="ag-theme-alpine-dark"> <AgGridReact onGridReady={onGridReady} defaultColDef={{ initialWidth: 270, sortable: true, filter: true, resizable: true, sizeColumnsToFit: true }} applyColumnDefOrder={true} headerCheckboxSelection={true} suppressPaginationPanel={true} columnDefs={gridcolumns} rowData={gridrowData} pagination={true} paginationAutoPageSize={true} rowSelection="multiple" onSelect={(event) => getSelectedRowData(event)} onSelectionChanged={getSelectedRowData}> </AgGridReact> </div> ) })
步骤2:父组件调用方式
import { useRef } from 'react' const ParentComponent = () => { // 声明ref接收子组件暴露的实例 const gridRef = useRef(null); // 刷新按钮点击逻辑 const handleRefresh = () => { // 直接调用子组件暴露的封装方法 gridRef.current?.refreshEntireGrid(); // 也可以直接操作暴露的api:gridRef.current?.gridApi?.refreshCells() } // 删除按钮点击逻辑 const handleRemove = () => { const selectedRows = gridRef.current?.getSelectedRows() || []; // 执行后续删除业务逻辑 } return ( <div> <button onClick={handleRefresh}>刷新表格</button> <button onClick={handleRemove}>删除选中行</button> {/* 给子组件传递ref */} <Grid ref={gridRef} tableData={gridData} columnData={activeColumnDef} onselectedRows={isDisabledOnMultipleRowSelect} /> </div> ) }
方案优势
- 可控性强:可以灵活选择只暴露封装好的业务方法(避免父组件随意操作api导致子组件状态不可控),也可以暴露全量api满足灵活的业务需求
- 拓展性好:后续需要新增导出、清空选中、调整列宽等父侧调用的能力,只需要在
useImperativeHandle中新增暴露项即可,无需修改props定义 - 符合官方规范:属于React原生支持的能力,无hack逻辑,可维护性高
内容的提问来源于stack exchange,提问作者user2128
相关产品推荐
相关产品推荐

