React组件给list集合追加节点并点击节点标签查看他的属性

我编写了一个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

img

img

img

问题出在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函数时,您将保存的数据合并到旧的数据中,而不是覆盖它。

我发的代码跟大佬的给的一模一样的,我在想是不是在打开的时候出问题了 保存没有问题 我调试的时候每次的值是不一样的

  • 这篇博客: React之实现前端分页中的 1. list请求函数 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  •  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);
     }, []);