react + redux 应用程序中的 agGrid 正在修改底层数据
agGrid in react + redux app is modifying underlying data
我在 React + redux 应用程序中使用最新的 agGrid Enterprise。
问题是我正在使用 agGrid 的内置编辑,这是在直接修改底层数据,即从 redux 存储返回的数组。这违反了不变性原则。有没有办法use/configure agGrid不修改数据而是:
- 对更改做出反应并调用一些包含有关更改的信息的回调
- 然后我可以更新 redux 存储(数组中的一项)
- 然后 agGrid 可以检测到数组中只有一个对象发生了变化,它只会刷新一行
谢谢
编辑:用更多细节扩展我的答案。
你必须设置一个"valueSetter"函数,并在每一列上设置它。最简单的方法是使用 defaultColDef。
快速说明,我的 table 中的每一行都是一个 'transaction',因此您会看到对交易的引用,而不是某种其他形式的标识。
例如:
<AgGridReact
// OPTIONS REQUIRED FOR OPTIMIZATION WITH REACT
reactNext
deltaRowDataMode
getRowNodeId={data => data.transaction_id}
// OTHER OPTIONS
rowSelection="multiple"
editType="fullRow"
// TABLE DATA
defaultColDef={{ ...defaultColDef, valueSetter }}
columnDefs={columns}
rowData={transactions}
// DISPLAY
rowClassRules={rowClassRules}
// EVENTS
onGridReady={onGridReady}
onRowEditingStarted={onRowEditingStarted}
onRowEditingStopped={onRowEditingStopped}
/>
别忘了react和redux需要的优化项。 (reactNext, deltaRowDataMode, getRowNodeId).
我定义的defaultColDef很简单:
defaultColDef: {
resizable: true,
sortable: true,
filter: true,
editable: true,
},
而 valueSetter 是一个定义非常简单的函数:
const valueSetter = (params) => {
allActions.columnEdit(params.data, params.oldValue, params.newValue, params.colDef);
return false;
};
其中 allActions.columnEdit 只是调用我在导入中定义的 Redux 操作,然后与 connect() 和 mapDispatchToProps 绑定。
return false 是防止状态发生变化所必需的。确保您的 redux 操作可以处理您需要做的任何事情。这是我的例子:
case actionTypes.COLUMN_EDIT: {
// FOR EACH COLUMN EDITED, CHECK IF ANYTHING CHANGED
// POST CHANGES TO NEW STATE
if (payload.oldValue !== payload.newValue) {
const account = 'acct01';
const column = payload.colDef.field;
const index = state[account].transactions.findIndex(
t => t.transaction_id === payload.t.transaction_id,
);
return produce(state, (draft) => {
const transaction = draft[account].transactions[index];
transaction[column] = payload.newValue;
});
}
return state;
}
希望这对您有所帮助。对于应该由 Ag-Grid 直接处理的内容,似乎有很多额外的解决方法,但也许他们会在未来进行一些开发。
我在 React + redux 应用程序中使用最新的 agGrid Enterprise。
问题是我正在使用 agGrid 的内置编辑,这是在直接修改底层数据,即从 redux 存储返回的数组。这违反了不变性原则。有没有办法use/configure agGrid不修改数据而是:
- 对更改做出反应并调用一些包含有关更改的信息的回调
- 然后我可以更新 redux 存储(数组中的一项)
- 然后 agGrid 可以检测到数组中只有一个对象发生了变化,它只会刷新一行
谢谢
编辑:用更多细节扩展我的答案。
你必须设置一个"valueSetter"函数,并在每一列上设置它。最简单的方法是使用 defaultColDef。 快速说明,我的 table 中的每一行都是一个 'transaction',因此您会看到对交易的引用,而不是某种其他形式的标识。
例如:
<AgGridReact
// OPTIONS REQUIRED FOR OPTIMIZATION WITH REACT
reactNext
deltaRowDataMode
getRowNodeId={data => data.transaction_id}
// OTHER OPTIONS
rowSelection="multiple"
editType="fullRow"
// TABLE DATA
defaultColDef={{ ...defaultColDef, valueSetter }}
columnDefs={columns}
rowData={transactions}
// DISPLAY
rowClassRules={rowClassRules}
// EVENTS
onGridReady={onGridReady}
onRowEditingStarted={onRowEditingStarted}
onRowEditingStopped={onRowEditingStopped}
/>
别忘了react和redux需要的优化项。 (reactNext, deltaRowDataMode, getRowNodeId).
我定义的defaultColDef很简单:
defaultColDef: {
resizable: true,
sortable: true,
filter: true,
editable: true,
},
而 valueSetter 是一个定义非常简单的函数:
const valueSetter = (params) => {
allActions.columnEdit(params.data, params.oldValue, params.newValue, params.colDef);
return false;
};
其中 allActions.columnEdit 只是调用我在导入中定义的 Redux 操作,然后与 connect() 和 mapDispatchToProps 绑定。 return false 是防止状态发生变化所必需的。确保您的 redux 操作可以处理您需要做的任何事情。这是我的例子:
case actionTypes.COLUMN_EDIT: {
// FOR EACH COLUMN EDITED, CHECK IF ANYTHING CHANGED
// POST CHANGES TO NEW STATE
if (payload.oldValue !== payload.newValue) {
const account = 'acct01';
const column = payload.colDef.field;
const index = state[account].transactions.findIndex(
t => t.transaction_id === payload.t.transaction_id,
);
return produce(state, (draft) => {
const transaction = draft[account].transactions[index];
transaction[column] = payload.newValue;
});
}
return state;
}
希望这对您有所帮助。对于应该由 Ag-Grid 直接处理的内容,似乎有很多额外的解决方法,但也许他们会在未来进行一些开发。