如何在 React 函数组件(useState 挂钩)中访问 ag-Grid API?
Posted
技术标签:
【中文标题】如何在 React 函数组件(useState 挂钩)中访问 ag-Grid API?【英文标题】:How to access ag-Grid API in React function component (useState hook)? 【发布时间】:2020-05-23 17:41:37 【问题描述】:在 React 函数 组件中访问 ag-Grid API 的最佳方式是什么?
我必须使用 API 中的一些方法(getSelectedNodes
、setColumnDefs
等),所以我在 onGridReady
事件处理程序中保存了对 API 的引用(使用 useState
钩子):
onGridReady=params =>
setGridApi(params.api);
然后我可以像这样调用 API:gridApi.getSelectedNodes()
我没有注意到这种方法有任何问题,但我想知道是否还有更多惯用方法?
堆栈:
ag-grid-community & ag-grid-react 22.1.1 反应 16.12.0【问题讨论】:
【参考方案1】:我们找到了使用 ref 最惯用的方式。因为 api 不是我们组件的状态。实际上可以简单地做:
<AgGridReact ref=grid/>
然后与
一起使用grid.current.api
这里是一个例子:
import React, useRef from 'react'
import AgGridReact from 'ag-grid-react'
import AgGridReact as AgGridReactType from 'ag-grid-react/lib/agGridReact'
const ShopList = () =>
const grid = useRef<AgGridReactType>(null)
...
return (
<AgGridReact ref=grid columnDefs=columnDefs rowData=shops />
)
这里的好处是,您可以访问 gridApi,但也可以访问 columnApi。就像这样:
// rendering menu to show/hide columns:
columnDefs.map(columnDef =>
<>
<input
type='checkbox'
checked=
grid.current
? grid.current.columnApi.getColumn(columnDef.field).isVisible()
: !(columnDef as hide: boolean ).hide
onChange=() =>
if (grid.current?.api)
const col = grid.current.columnApi.getColumn(columnDef.field)
grid.current.columnApi.setColumnVisible(columnDef.field, !col.isVisible())
grid.current.api.sizeColumnsToFit()
setForceUpdate(x => ++x)
/>
<span>columnDef.headerName</span>
</>
)
【讨论】:
这应该是新接受的答案。最好符合官方文档。 作为建议,您可能需要在const grid = useRef<AgGridReactType>(null)
行上方添加 // prettier-ignore
以防止在 VS Code 中自动格式化它。
很好的答案。它为打字稿用户提供了一种他们可以使用的类型,而不是any
。但只是想知道,为什么这个奇怪的导入import AgGridReact as AgGridReactType from 'ag-grid-react/lib/agGridReact'
?您能否将我指向使用/说明的官方文档。我原以为这是一个“***”模块,就像深入到另一个模块的lib
一样。
我现在不能肯定地告诉你,但我认为该类型要么没有暴露在顶层,要么暴露了同名的类型,但打字略有错误。
在现代 ts 4.X 中你实际上需要import type AgGridReact as AgGridReactType from 'ag-grid-react/lib/agGridReact';
【参考方案2】:
嗯,我正在我的项目中这样做。你可以使用useRef
钩子来存储gridApi
。
const gridApi = useRef();
const onGridReady = params =>
gridApi.current = params.api; // <== this is how you save it
const datasource = getServerDataSource(
gridApi.current,
size: AppConstants.PAGE_SIZE,
url: baseUrl,
defaultFilter: props.defaultFilter
);
gridApi.current.setServerSideDatasource(datasource); // <== this is how you use it
;
【讨论】:
这似乎也是可行的选择!我希望 ag-Grid 团队的某个人在 SE 上观察 ag-grid 标签并提供权威答案...:/ @user1068352 是的,我也是。我对我的 SE 帐户上的功能组件 agGrid 也有几个问题。如果对您有帮助,请您投票并接受答案:) 我会尝试联系ag团队以获得官方推荐。如果它与 useRef 匹配,我肯定会接受你的回答。记得给问题点赞 ;)【参考方案3】:我遇到了同样的问题,但这里有一个解决方法,至少可以让您选择选定的行。基本上我正在做的是将 api 从 agGrid 回调发送到另一个函数。具体来说,我使用 OnSelectionChanged 回调来获取当前行节点。示例如下:
const onSelectionChanged = params =>
setDetails(params.api.getSelectedRows());
;
return (<AgGridReact
columnDefs=agData.columnDefs
rowSelection='single'
enableCellTextSelection=true
defaultColDef=
resizable: true,
rowHeight=50
rowData=agData.rowData
onCellFocused=function(params)
if (params.rowIndex != null)
let nNode = params.api.getDisplayedRowAtIndex(params.rowIndex);
nNode.setSelected(true, true);
onSelectionChanged=function(params)
onSelectionChanged(params);
params.api.sizeColumnsToFit();
onGridReady=function(params)
let gridApi = params.api;
gridApi.sizeColumnsToFit();
deltaRowDataMode=true
getRowNodeId=function(data)
return data.id;
/>);
【讨论】:
我希望能够持久访问 API - 我什至尝试将 api 挂钩到组件状态,但它似乎失去了原始网格实例的范围......它似乎创建了新实例与初始网格 API 无关。仅供参考,我将 React Boilerplate 与 Redux、Sagas、Reselect 等一起使用。 你试过useState钩子吗?它对我来说很好。【参考方案4】:只是想知道,为什么需要使用 state-hook,因为 gridApi
在生命周期内不会改变。
如果您检查 ag-grid 团队示例,您会发现他们只使用属性绑定:
onGridReady = params =>
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
;
所以我想,您不需要使用state
来存储API
引用。
【讨论】:
您能否指出您提到的在函数(功能)组件(不是基于类的组件)中使用 this.gridApi 的 ag-grid 团队示例? 从文档中挑选任何东西(并在组合框中选择 ReactJS)just an example 这些是基于类的示例。我的问题明确是关于功能组件的。 请注意,所有示例目前都是用类编写的,例如:class GridExample extends Component
@user1068352 抱歉没有明白你在找什么以上是关于如何在 React 函数组件(useState 挂钩)中访问 ag-Grid API?的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中,如何使用 hook useState 来设置数据?
React Hooks --- useState 和 useEffect