自在猫先生 2023-05-08 11:54 采纳率: 62.9%
浏览 32
已结题

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

  • 写回答

4条回答 默认 最新

  • messilion 2023-05-08 13:29
    关注

    问题出在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');
      }
    };
    
    
    

    ```

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月12日
  • 修改了问题 5月8日
  • 创建了问题 5月8日

悬赏问题

  • ¥15 上传图片时提交的存储类型
  • ¥15 Ubuntu开机显示器只显示kernel,是没操作系统(相关搜索:显卡驱动)
  • ¥15 VB.NET如何绘制倾斜的椭圆
  • ¥15 在rhel8中安装qemu-kvm时遇到“cannot initialize crypto:unable to initialize gcrypt“报错”
  • ¥15 arbotix没有/cmd_vel话题
  • ¥15 paddle库安装时报错提示需要安装common、dual等库,安装了上面的库以后还是显示报错未安装,要怎么办呀?
  • ¥20 找能定制Python脚本的
  • ¥15 odoo17的分包重新供应路线如何设置?可从销售订单中实时直接触发采购订单或相关单据
  • ¥15 用C语言怎么判断字符串的输入是否符合设定?
  • ¥15 通信专业本科生论文选这两个哪个方向好研究呀