-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🐛[BUG] EditableProTable 结合 proForm 使用,在表格头部插入数据时,导致其他数据丢失 #6572
Comments
删除时也有此问题 |
从您提供的信息和截图来看,问题出现在通过 ProForm 的表单项来添加、修改和删除 EditableProTable 数据时,并且机制是通过 Redux 存储数据,同时在删、增、改某行数据的时候,其他行数据内容丢失。 可能原因: EditableProTable 组件使用了 redux 作为数据存储机制,从数据流架构上分析,应该是在数据分发时,造成了数据的更新错误,导致某些行数据呈 “空” 状态。 解决方案:
代码示例:您可以尝试使用 Immer.js 实现带有 Redux 的 EditableProTable。如下: 在你的 reducer 中: import produce from "immer";
// 其他设置...
const reducer = produce((draftState, action) => {
switch (action.type) {
case "addRow":
// 这里是逻辑代码
// 此处使用 Immer.js
const newData = { title: "测试标题", desc: "测试描述" };
draftState.dataSource = [...draftState.dataSource, newData];
break;
case "updateRow":
const { rowIndex, columnName, columnValue } = action.payload;
// 这里也使用 Immer.js,设置新的 dataSource
draftState.dataSource = draftState.dataSource.map((item, index) => {
if (index === rowIndex) {
return { ...item, [columnName]: columnValue };
}
return item;
});
break;
case "deleteRow":
const { rowIndex } = action.payload;
// 删除一个row调用Immer.js
draftState.dataSource = draftState.dataSource.slice(rowIndex);
break;
default:
return draftState;
}
});
export default reducer; 在您的 EditableProTable 组件中: import { EditableProTable } from "@ant-design/pro-table";
import { produce } from "immer";
const Page: React.FC<PageProps> = () => {
const [dataSource, setDataSource] = useState([]);
const actionRef = useRef<ActionType>();
const reducer = useReducer<Reducer<PageState, PageActions>>(pageReducer, {
//初始化dataSource和其他状态
dataSource: [],
loading: false,
count: 2
});
const handleRowDelete = (rowIndex: number) => {
const [state, dispatch] = reducer;
dispatch({ type: "deleteRow", payload: { rowIndex } });
};
const handleUpdateRow = (rowIndex: number, columnName: string, columnValue: string) => {
const [state, dispatch] = reducer;
dispatch({ type: "updateRow", payload: { rowIndex, columnName, columnValue } });
};
const handleRowAdd = () => {
const [state, dispatch] = reducer;
dispatch({ type: "addRow" });
};
//封装组件逻辑
const handleTableRowChange = (
list: PageState["dataSource"],
record: PageState["dataSource"][0],
_, //没有变化的列值
action: string
) => {
switch (action) {
case "update":
const { index, key, value } = record;
console.log("update", { index, key, value });
handleUpdateRow(index, key, value);
break;
case "delete":
const { index } = record;
console.log("delete", index);
handleRowDelete(index);
break;
default:
break;
}
setDataSource(list);
};
return (
<Form>
<ProFormList
name="users"
creatorButtonProps={{
position: "top",
creatorButtonText: "新增一行",
max: 5,
onCreator: handleRowAdd
}}
itemRender={(item, { list, action }, index) => {
return (
<Form.Item>
<EditableProTable
rowKey="index"
columns={[
{
title: "标题",
dataIndex: "title",
//此处设置一个编辑框
renderFormItem: () => <Input />
},
{
title: "描述",
dataIndex: "desc",
// 此处必须设置为textarea,否则过长的字符串会出现无法编辑的错误
renderFormItem: () => <TextArea rows={1} />
}
]}
value={list}
onChange={(newList) => handleTableRowChange(newList, list, action)}
onDelete={(a, record) => handleTableRowChange(a, record, action, "delete")}
recordCreatorProps={false}
/>
</Form.Item>
);
}}
></ProFormList>
</Form>
);
}; 通过改用 Immer.js,你可以简化你的 reducer 操作,生成可读性更高的代码,同时,也可以优化内存的使用,减少可能存在的无谓的数据复制。 希望以上方案可以帮到您,若有不明白的地方或遇到新问题,请在评论中详细描述,并附上代码和相关参数,以便于问题精确定位和排查。 |
我也遇到了,只能通过这种方式吗 |
提问前先看看:
https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md
🐛 bug 描述
EditableProTable 结合 proForm 使用,在表格头部插入数据时,导致其他数据丢失
📷 复现步骤
🏞 期望结果
💻 复现代码
参考 sandbox
© 版本信息
🚑 其他信息
The text was updated successfully, but these errors were encountered: