自在猫先生 2023-04-27 18:34 采纳率: 62.9%
浏览 57
已结题

React 组件之间的传值,保存数据到树形节点

我编写了一个组件,父组件打开子组件中的窗口输入数据进行保存,到树形组件下面进行展示,我在保存的时候一直抛出异常提示找不到这个属性

保存数据的时候父级组件这个方法异常了找不到节点TypeError: Cannot read properties of undefined (reading 'children')
以下是完整代码可以运行
父组件
import React, { useState } from 'react';
import {TreeSelect} from 'antd';
import ProjectComponets from '../ModalForm/ProjectComponets';
import { PlusCircleOutlined } from '@ant-design/icons';
import FormComponets from '../ModalForm/FormComponets';
const { SHOW_PARENT } = TreeSelect;
function TreeComponets(){

    const [value, setValue] = useState(['0-0-0']);
    const [treeData,setData] = useState([]); // 初始化树形数据
    const [searchValue, setSearchValue] = useState('');
    const [selectedNode, setSelectedNode] = useState(null);
    const [isModalOpenForm,setIsModalOpenForm]=useState(false);
    const [FormSelectedNode,setFormSelectedNode]=useState(null);
    const onChange = function (newValue) {
        setValue(newValue);
    };

    const onSearch = (searchText) => {
        setSearchValue(searchText);
    };

    const tProps = {
    treeData,
    value,
    onChange,
    treeCheckable: true,
    showCheckedStrategy: SHOW_PARENT,
    placeholder: 'Please select',
    style: {
        width: '100%',
    },
    filterTreeNode: (node) => {
        return node.title.toLowerCase().includes(searchValue.toLowerCase());
    },
    treeDefaultExpandAll: true,
    onSearch: onSearch,
    onSelect: (selectedValue, node) => {
        setSelectedNode(node);
      },
   };
    
   //接收项目组件传递的数据
    const handleSave=(formData)=>{
        debugger
        // setData([...treeData, formData]); // 将表单数据添加到数组中
        const randomId = `SL-${Math.floor(Math.random() * 1000000)}`;
        const newNode = {
        title: `${formData.newNodeNo}-${formData.newNodeName}`,
        value: randomId,
        children: [
        { title: `${formData.newNodeNo}-${formData.newNodePName} `, value: `${randomId}-1` },
        { title: <PlusCircleOutlined onClick={showModalForm} /> , value: `${randomId}-2` }
        ],
    };

    const newData = [...treeData];
    if (!selectedNode) {
      newData.push(newNode);
    } else {
      selectedNode.children.push(newNode);
    }
    setData(newData);
    }

    const onSelect = (value, node) => {
        debugger
        console.log('onSelect', value, node);
        setSelectedNode(node);
      };
    const showModalForm=()=>{
     setIsModalOpenForm(true);
     setFormSelectedNode(selectedNode); // 将选中的节点信息保存到状态中
    };

    const handleCloseModal=()=>{
     setIsModalOpenForm(false);
    };

    const FormSave = (data, selectedNode) => {
        debugger
        const randomId = `SL-${Math.floor(Math.random() * 1000000)}`;
        const newNode = {
            title: data.FormName,
            value: randomId
        };
        const newData = [...treeData];
        selectedNode.children.push(newNode);
        setData(newData);
      };

     return(

        <div>
            <ProjectComponets onSave={handleSave} />
            <TreeSelect {...tProps} onSelect={onSelect}  />
            <FormComponets visible={isModalOpenForm} onClose={handleCloseModal} onSave={FormSave} />
        </div>
     );
;
}
export default TreeComponets;
子组件
import React, { useState } from 'react';
import { Button,Modal,Input,Select,Form,Checkbox} from 'antd';

function FormComponets({ visible, onClose,onSave }){

    const plainOptions = ['button', 'Lable', 'combox'];

    const options = [
    { label: 'Grid', value: 'Apple' },
    { label: 'Tab', value: 'Pear' },
    { label: 'Listview', value: 'Orange' },
    ];
    
    const [checkedList, setCheckedList] = useState([...plainOptions, ...options.map((option) => option.value)]);
    const [indeterminate, setIndeterminate] = useState(true);
    const [checkAll, setCheckAll] = useState(false);
    const [form] = Form.useForm();//Form.useForm()生成了一个form实例,并将其绑定到了Form组件上
    const onCheckAllChange = (e) => {
        setCheckedList(e.target.checked ? [...plainOptions, ...options.map((option) => option.value)] : []);
        setIndeterminate(false);
        setCheckAll(e.target.checked);
    };
    const onCheckReverseChange = () => {
        const newCheckedList = [];
        [...plainOptions, ...options.map((option) => option.value)].forEach((value) => {
        if (!checkedList.includes(value)) {
            newCheckedList.push(value);
        }
        });
        setCheckedList(newCheckedList);
        setIndeterminate(!!newCheckedList.length && newCheckedList.length < plainOptions.length + options.length);
        setCheckAll(newCheckedList.length === plainOptions.length + options.length);
    };
    const onChange = (checkedValues) => {
        setCheckedList(checkedValues);
        setIndeterminate(!!checkedValues.length && checkedValues.length < plainOptions.length + options.length);
        setCheckAll(checkedValues.length === plainOptions.length + options.length);
    };

    const onFinish = (values) => {
        onSave(values); // 将表单数据传递给父组件进行保存
        visible(false); // 关闭Modal
        form.resetFields(); //清空表单数据
      };

    return (
        <div>
          <Modal title="定义窗体信息" visible={visible} onCancel={onClose} footer={null}>
            <Form
           onFinish={onFinish}
            >
              <Form.Item
                label="form name"
                name="FormName"
                rules={[{ required: true, message: 'Please enter the scheme name!' }]}
              >
                <Input type="text" style={{ width: '80%' }} placeholder="Please enter the form name" />
              </Form.Item>
              <Form.Item
                label="object name"
                name="ObjectName"
                rules={[{ required: true, message: 'Please enter the object name!' }]}
              >
                <Input type="text" style={{ width: '80%' }} placeholder="Please enter the form name" />
              </Form.Item>

              <Form.Item
                label="English name"
                name="EnglishName"
                rules={[{ required: true, message: 'Please enter the Eeglish name!' }]}
              >
                <Input type="text" style={{ width: '80%' }} placeholder="Please enter the form name" />
              </Form.Item>
              {/* 选择框区域 */}
              <Form.Item>
                <>
                  <Checkbox.Group options={plainOptions.concat(options)} value={checkedList} onChange={onChange} />
                  <br />
                  <br />
                  <Checkbox
                    indeterminate={indeterminate}
                    onChange={onCheckAllChange}
                    checked={checkAll}
                    disabled={checkedList.length === 0}
                  >
                    全选
                  </Checkbox>
                  <Checkbox
                    style={{ marginLeft: '10px' }}
                    onClick={onCheckReverseChange}
                  >
                    反选
                  </Checkbox>
                </>
              </Form.Item>
              <Form.Item wrapperCol={{ offset: 18, span: 16 }}>
             <Button type="primary" htmlType="submit" >
               Submit
              </Button>
              </Form.Item>
            </Form>
          </Modal>
        </div>
      );


}export default FormComponets
这个 selectedNode.children.push(newNode);一直异常
  • 写回答

2条回答 默认 最新

  • 崽崽的谷雨 2023-04-27 20:02
    关注

    说明 selectedNode 没有children属性 你打印一下看看selectedNode.children.push(newNode); 的上面打印 或者 你加个判断

    if (selectedNode.children) {
            selectedNode.children.push(newNode);
          }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月12日
  • 已采纳回答 5月4日
  • 创建了问题 4月27日