我编写了一个React的程序,点击新建添加节点的时候,保存进去的数据传递给子组件,在子组件窗体进行显示。
我遇到了一个问题是,虽然的每次都新增成功了,但是我最后一次新增的数据会覆盖原来的数据。
import { Avatar, List } from 'antd';
import React, { useState } from 'react';
import ProjectComponets from '../ModalForm/ProjectComponets';
import { PlusCircleOutlined,SolutionOutlined,DeleteOutlined } from '@ant-design/icons';
import SolutionComponets from './SolutionComponets';
function ListTreeComponets () {
const [listData,setListData]=useState([]);
const randomId = `SL-${Math.floor(Math.random() * 1000000)}`;
const [isModalOpenForm,setIsModalOpenForm]=useState(false);
const [isModalOpenBaic,setIsModalOpenBasic]=useState(false);
const [AttributeData, setAttributeData] = useState(null);
const handleSave=(formData)=>{
const newAttributeData = { ...AttributeData, ...formData };
// 将新数据与旧数据合并,不替换旧数据
setAttributeData({...newAttributeData});
const newNode = {
title: (
<span>
{`${formData.newNodeNo}-${formData.newNodeName}`}
<DeleteOutlined onClick={(event) => handleDelete(`${formData.newNodeNo}-${formData.newNodeName}`, event)} />
</span>
),
value: `${formData.newNodeNo}-${formData.newNodeName}`, // 使用相同格式作为 value
children: [
{ title: `${formData.ProjecTtype}-${formData.Parentlevel} `, value: `${randomId}-1` },
{ title: <PlusCircleOutlined onClick={showModalForm} />, value: `${formData.newNodeNo}-${formData.newNodeName}-2`, children: [] }
]
};
const isDuplicate = (node, listData) =>
listData.some((item) => JSON.stringify(item) === JSON.stringify(node));
if (!isDuplicate(newNode, listData)) { // 比较节点的所有属性值
setListData([...listData, newNode]);
} else {
console.log('This node already exists in the list');
}
}
const showModalForm=()=>{
}
const showModalBaisc=()=>{
setIsModalOpenBasic(true);
};
const handleCloseModalBasic=()=>{
setIsModalOpenBasic(false);
};
const handleDelete=(value,event)=>{
event.preventDefault();
const newData = listData.filter((node) => node.value !== value);
setListData(newData);
}
return(
<div>
<ProjectComponets
onSave={(formData) => handleSave(formData, setListData)}
/>
<SolutionComponets
visible={isModalOpenBaic} AttributeData={AttributeData}
onClose={handleCloseModalBasic}
/>
<List style={{width:'50%'}}
itemLayout="horizontal"
dataSource={listData}
renderItem={(item, index) => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src={`https://xsgames.co/randomusers/avatar.php?g=pixel&key=${index}`} />}
title={<a href="https://ant.design">{item.title}</a>}
description="This is a solution project for generating Word documents"
/>
<PlusCircleOutlined onClick={showModalForm} style={{ marginLeft: '20px', marginRight: '10px' }} />
<SolutionOutlined onClick={showModalBaisc}/>
</List.Item>
)}
/>
</div>
);
};
export default ListTreeComponets;
import { Drawer } from 'antd';
import React, { useState } from 'react';
function SolutionComponets({visible,onClose,AttributeData}){
debugger
const [open, setOpen] = useState(false);
const handleCloseDrawer = () => {
setOpen(false);
onClose(); // 调用父组件传递的onClose函数
};
return (
<>
<Drawer title="窗体属性" visible={visible} placement="right" onClose={handleCloseDrawer}>
<p> {AttributeData ? AttributeData.newNodeNo : ''}</p>
<p> {AttributeData ? AttributeData.newNodeName : ''}</p>
<p> {AttributeData ? AttributeData.ProjecTtype : ''}</p>
<p> {AttributeData ? AttributeData.Parentlevel : ''}</p>
</Drawer>
</>
);
}
export default SolutionComponets
问题出在setState上,最后一次新增的数据覆盖原来的数据是因为在handleSave函数中,setAttributeData只是将新数据与旧数据合并,而不是将新数据添加到旧数据中。正确的做法应该是将新数据添加到旧数据中,然后再将合并后的数据传递给setAttributeData函数。修改代码如下:
```javascript
const handleSave = (formData) => {
const newAttributeData = { ...AttributeData, ...formData };
// 将新数据与旧数据合并,不替换旧数据
setAttributeData(newAttributeData); // 修改这一行
const newNode = {
title: (
<span>
{`${formData.newNodeNo}-${formData.newNodeName}`}
<DeleteOutlined onClick={(event) => handleDelete(`${formData.newNodeNo}-${formData.newNodeName}`, event)} />
</span>
),
value: `${formData.newNodeNo}-${formData.newNodeName}`, // 使用相同格式作为 value
children: [
{ title: `${formData.ProjecTtype}-${formData.Parentlevel} `, value: `${randomId}-1` },
{ title: <PlusCircleOutlined onClick={showModalForm} />, value: `${formData.newNodeNo}-${formData.newNodeName}-2`, children: [] }
]
};
const isDuplicate = (node, listData) => listData.some((item) => JSON.stringify(item) === JSON.stringify(node));
if (!isDuplicate(newNode, listData)) { // 比较节点的所有属性值
setListData([...listData, newNode]);
} else {
console.log('This node already exists in the list');
}
};
```
以下回答参考GPT并且由Bony-整理:
根据您提供的代码,问题在于您每次调用handleSave
函数时都使用setAttributeData
将新的数据覆盖了旧的数据。因此,最后一次保存的数据会替换之前的数据。您需要将新的数据合并到旧的数据中,而不是替换它。为此,您可以使用展开运算符来将新数据合并到旧数据中,如下所示:
const handleSave = (formData) => {
const newAttributeData = { ...AttributeData, ...formData };
// 将新数据与旧数据合并,不替换旧数据
setAttributeData({...newAttributeData});
const newNode = {
title: (
<span>
{`${formData.newNodeNo}-${formData.newNodeName}`}
<DeleteOutlined onClick={(event) => handleDelete(`${formData.newNodeNo}-${formData.newNodeName}`, event)} />
</span>
),
value: `${formData.newNodeNo}-${formData.newNodeName}`, // 使用相同格式作为 value
children: [
{ title: `${formData.ProjecTtype}-${formData.Parentlevel} `, value: `${randomId}-1` },
{ title: <PlusCircleOutlined onClick={showModalForm} />, value: `${formData.newNodeNo}-${formData.newNodeName}-2`, children: [] }
]
};
const isDuplicate = (node, listData) =>
listData.some((item) => JSON.stringify(item) === JSON.stringify(node));
if (!isDuplicate(newNode, listData)) { // 比较节点的所有属性值
setListData([...listData, newNode]);
} else {
console.log('This node already exists in the list');
}
}
在上述代码中,setAttributeData
函数使用展开运算符将旧数据和新数据合并成一个新对象,并使用setAttributeData
函数将其设置为新的AttributeData
状态值。这样,每次调用handleSave
函数时,您将保存的数据合并到旧的数据中,而不是覆盖它。
我发的代码跟大佬的给的一模一样的,我在想是不是在打开的时候出问题了 保存没有问题 我调试的时候每次的值是不一样的
const requestList = useCallback(async (params: CompareFreAnalyParams) => {
setLoading(true);
//每次请求时需要将数组内原有数据清空
setList([]);
try {
const { result } = await fetchCompareFreAnalyList(params);
setSumList(result);
//arrSplit 分页函数
setList(arrSplit(result, 1, pageSize));
} catch (e) {
message.warn(e.message || '获取数据失败');
}
setLoading(false);
}, []);