AG-Grid React,在数据更改时无法让自定义单元格渲染器更新。函数组件的行为不同于 class 个组件
AG-Grid React, trouble getting custom cell renderer to update when data changes. Function components are behaving differently than class components
我在整个 React 应用程序中使用 AG-Grid,在一些情况下,我希望 cellRenderer 在网格数据更改时更新。在以下两种情况下,cellRenderer 最初会正确加载,但不会在数据更改时更新:
- 用户编辑了一个可编辑的单元格并更改了值。
- 服务器更新redux中的grid数据
看看这个codesandbox
在这个例子中,我用一个可编辑的单元格重新创建了第一个用例,并使用了一个 class 组件和一个函数组件。将 onCellValueChanged 与 params.api.refreshCells() 一起使用,我能够更新 class 组件,但不能更新函数组件。
第一个问题:如何让 React 函数组件使用新的 props 重新渲染,就像 class 组件在 codesandbox 示例中重新渲染一样?
第二个问题:是否有更好的方法来更新 cellRenderer,而无需在数据更新时卸载并重新安装列中的每个单元格?
在此先感谢您的帮助和指导!
...
this.state = {
columnDefs: [
{
headerName: "Editable Country",
editable: true,
field: "country",
width: 200
},
{
headerName: "Class Render",
cellRendererFramework: GridCellClass,
colId: "class-renderer",
width: 200
},
{
headerName: "Function Render",
cellRendererFramework: GridCellFunction,
colId: "function-renderer",
width: 200
}
],
rowData: []
};
}
...
<AgGridReact
rowModelType="infinite"
columnDefs={this.state.columnDefs}
enableColResize={true}
rowClassRules={{
california: function(params) {
return params.data.country === "California";
}
}}
onCellValueChanged={function(params) {
return params.api.refreshCells({
force: true,
columns: ["class-renderer", "function-renderer"]
});
}}
onGridReady={this.onGridReady.bind(this)}
rowData={this.state.rowData}
/>
...
// This one updates!
import React, { Component } from "react";
class GridCellClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { data } = this.props;
return (
<div>
{data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
</div>
);
}
}
export default GridCellClass;
// This one does not update.
import React from "react";
function GridCellFunction(props) {
const { data } = props;
return (
<div>
{data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
</div>
);
}
export default GridCellFunction;
1.单元格渲染器函数
当您没有刷新要求时,应使用单元格渲染器函数,这在 ag-grid 文档中有所提及。
根据docs-
Use the function variant of a cell renderer if you have no refresh or
cleanup requirements (ie you don't need to implement the refresh or
destroy functions).
这就是您的单元格渲染器函数不刷新的原因。
为了解决你的问题,你可以这样做-
onCellValueChanged={function(params) {
if(params.column.getId() === 'country') {
params.api.redrawRows();
}
}}
2.单元格渲染器组件
你的 GridCellClass
在 api.refreshCells()
上工作的原因是网格为你处理 refresh()
因为你没有在你的 GridCellClass
中实现 refresh()
零件。
这意味着如果基础数据发生变化,您的组件将被销毁并重新创建。
3.RefreshCells
另请注意,使用 api.refreshCells()
不会按原样工作,因为 ag-grid 使用变化检测来刷新单元格,同时确定要刷新的单元格,因为基本上其他 2 列的值不会改变但事实上,它们在 cellRenderer 本身中发生了变化。
然而,以下内容适用于 GridCellClass
,因为您通过传递 force:true
、
来禁用更改检测
params.api.refreshCells({
force: true
});
来自文档-
Change detection will be used to refresh only cells who's display cell
values are out of sync with the actual value. If using a cellRenderer
with a refresh method, the refresh method will get called.
我在整个 React 应用程序中使用 AG-Grid,在一些情况下,我希望 cellRenderer 在网格数据更改时更新。在以下两种情况下,cellRenderer 最初会正确加载,但不会在数据更改时更新:
- 用户编辑了一个可编辑的单元格并更改了值。
- 服务器更新redux中的grid数据
看看这个codesandbox
在这个例子中,我用一个可编辑的单元格重新创建了第一个用例,并使用了一个 class 组件和一个函数组件。将 onCellValueChanged 与 params.api.refreshCells() 一起使用,我能够更新 class 组件,但不能更新函数组件。
第一个问题:如何让 React 函数组件使用新的 props 重新渲染,就像 class 组件在 codesandbox 示例中重新渲染一样?
第二个问题:是否有更好的方法来更新 cellRenderer,而无需在数据更新时卸载并重新安装列中的每个单元格?
在此先感谢您的帮助和指导!
...
this.state = {
columnDefs: [
{
headerName: "Editable Country",
editable: true,
field: "country",
width: 200
},
{
headerName: "Class Render",
cellRendererFramework: GridCellClass,
colId: "class-renderer",
width: 200
},
{
headerName: "Function Render",
cellRendererFramework: GridCellFunction,
colId: "function-renderer",
width: 200
}
],
rowData: []
};
}
...
<AgGridReact
rowModelType="infinite"
columnDefs={this.state.columnDefs}
enableColResize={true}
rowClassRules={{
california: function(params) {
return params.data.country === "California";
}
}}
onCellValueChanged={function(params) {
return params.api.refreshCells({
force: true,
columns: ["class-renderer", "function-renderer"]
});
}}
onGridReady={this.onGridReady.bind(this)}
rowData={this.state.rowData}
/>
...
// This one updates!
import React, { Component } from "react";
class GridCellClass extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { data } = this.props;
return (
<div>
{data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
</div>
);
}
}
export default GridCellClass;
// This one does not update.
import React from "react";
function GridCellFunction(props) {
const { data } = props;
return (
<div>
{data.country === "California" ? "CALIFORNIA!!!" : "Not California"}
</div>
);
}
export default GridCellFunction;
1.单元格渲染器函数
当您没有刷新要求时,应使用单元格渲染器函数,这在 ag-grid 文档中有所提及。
根据docs-
Use the function variant of a cell renderer if you have no refresh or cleanup requirements (ie you don't need to implement the refresh or destroy functions).
这就是您的单元格渲染器函数不刷新的原因。
为了解决你的问题,你可以这样做-
onCellValueChanged={function(params) {
if(params.column.getId() === 'country') {
params.api.redrawRows();
}
}}
2.单元格渲染器组件
你的 GridCellClass
在 api.refreshCells()
上工作的原因是网格为你处理 refresh()
因为你没有在你的 GridCellClass
中实现 refresh()
零件。
这意味着如果基础数据发生变化,您的组件将被销毁并重新创建。
3.RefreshCells
另请注意,使用 api.refreshCells()
不会按原样工作,因为 ag-grid 使用变化检测来刷新单元格,同时确定要刷新的单元格,因为基本上其他 2 列的值不会改变但事实上,它们在 cellRenderer 本身中发生了变化。
然而,以下内容适用于 GridCellClass
,因为您通过传递 force:true
、
params.api.refreshCells({
force: true
});
来自文档-
Change detection will be used to refresh only cells who's display cell values are out of sync with the actual value. If using a cellRenderer with a refresh method, the refresh method will get called.