我编写了一个react项目,写了一个子组件,子组件中进行输入数据的操作,然后通过组件信息传递在父组件中进行保存数据,我在保存数据的时候怎么保存都保存不成功,我只想在那个+号的节点下再新建一个节点,我我编写了一个fornsave但是实现不了这个效果
完整代码如下
需要安装的组件 npm install antd,npm install @ant-design/icons
子组件
import React, { useState } from 'react';
import { Button,Modal,Input,Select,Form,Checkbox} from 'antd';
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 [FormName, setFormName] = useState('');
const [ObjectName, setObjectName] = useState('');
const [EnglishName, setEnglishName] = useState('');
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,value,node) => {
onSave(values, value, node); // 将表单数据、value和node传递给父组件进行保存
// visible(false); // 关闭Modal
form.setFieldsValue(values);
form.resetFields(); //清空表单数据
};
return (
<div>
<Modal title="定义窗体信息" visible={visible} onCancel={onClose} footer={null}>
<Form form={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"
value={FormName} onChange={e => setFormName(e.target.value)}
/>
</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"
value={ObjectName} onChange={e => setObjectName(e.target.value)}
/>
</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"
value={EnglishName} onChange={e => setEnglishName(e.target.value)}
/>
</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
import React, { useState } from 'react';
import { Button,Modal,Input,Select,Form} from 'antd';
function ProjectComponets({ onSave }){
const [isModalOpen, setIsModalOpen] = useState(false);
const [form] = Form.useForm();//Form.useForm()生成了一个form实例,并将其绑定到了Form组件上
//初始化下拉框值
const options = [
{
value: '解决方案',
label: '解决方案',
},
{
value: '项目',
label: '项目',
}
];
const showModal = () => {
setIsModalOpen(true);
};
//关闭窗口
const handleCancel = () => {
setIsModalOpen(false);
};
const onFinish = (values) => {
onSave(values); // 将表单数据传递给父组件进行保存
setIsModalOpen(false); // 关闭Modal
form.resetFields(); //清空表单数据
};
return (
<div>
<>
<Button type="primary" onClick={showModal} >
新建解决方案
</Button>
<Modal title="添加解决方案" footer={null} visible={isModalOpen} onCancel={handleCancel}>
<Form form={form}
name="basic"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
style={{ maxWidth: 600 }}
initialValues={{ remember: true }}
onFinish={onFinish}
autoComplete="off"
>
<Form.Item
label="scheme number"
name="newNodeNo"
rules={[{ required: true, message: 'Please enter the scheme number!' }]}
>
<Input
type="text"
style={{ width: '80%' }}
placeholder="Please enter the scheme number!"
/>
</Form.Item>
<Form.Item
label="scheme name"
name="newNodeName"
rules={[{ required: true, message: 'Please enter the scheme name!' }]}
>
<Input
type="text"
style={{ width: '80%' }}
placeholder="Please enter the scheme name"
/>
</Form.Item>
<Form.Item
label="project name"
name="newNodePName"
rules={[{ required: true, message: 'Please enter a project name!' }]}
>
<Input
type="text"
style={{ width: '80%' }}
placeholder="Please enter a project name"
/>
</Form.Item>
<Form.Item
label="Project type"
name="Project type"
>
<Select style={{ width: '80%' }} defaultValue="解决方案" options={options} />
</Form.Item>
<Form.Item
label="Parent level"
name="Parent level"
rules={[{ required: false, message: 'Parent level!' }]}
>
<Input
type="text"
style={{ width: '80%' }}
placeholder=""
/>
</Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button type="primary" htmlType="submit" >
Submit
</Button>
</Form.Item>
</Form>
</Modal>
</>
</div>
);
}
export default ProjectComponets
父组件
import React, { useState } from 'react';
import {TreeSelect,Button} from 'antd';
import ProjectComponets from '../ModalForm/ProjectComponets';
import { PlusCircleOutlined } from '@ant-design/icons';
import FormComponets from '../ModalForm/FormComponets';
import BasicDrawer from '../ModalForm/BasicDrawer';
const { SHOW_PARENT } = TreeSelect;
function TreeComponets(){
const [value, setValue] = useState(['0-0-0']);
const [treeData, setTreeData] = useState([]);// 初始化树形数据
const [searchValue, setSearchValue] = useState('');
const [selectedNode, setSelectedNode] = useState(null);
const [isModalOpenForm,setIsModalOpenForm]=useState(false);
const [isModalOpenBaic,setIsModalOpenBasic]=useState(false);
const [basicData, setBasicData] = useState(null);
const randomId = `SL-${Math.floor(Math.random() * 1000000)}`;
const onChange = function (newValue,value, node,) {
console.log(newValue)
setValue(newValue);
};
const onSearch = (searchText) => {
setSearchValue(searchText);
};
const onSelect = (value, node) => {
console.log(value)
setSelectedNode(node);
};
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,
};
//接收项目组件传递的数据
const handleSave=(formData)=>{
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);
}
setTreeData(newData);
}
const showModalForm=()=>{
setIsModalOpenForm(true);
};
const handleCloseModal=()=>{
setIsModalOpenForm(false);
};
const showModalBaisc=()=>{
setIsModalOpenBasic(true);
};
const FormSave = (data, value, node, setTreeData) => {
const randomId = `SL-${Math.floor(Math.random() * 1000000)}`;
const newNode = {
title: data.FormName,
value: randomId,
key: randomId,
onClick: () => showModalBaisc(),
children: [
{ title: `${data.ObjectName}`, value: `${randomId}-2` },
{ title: `${data.EnglishName}`, value: `${randomId}-3` }
]
};
// 找到目标节点并添加新的子节点
const newData = [...treeData];
const addDataToNode = (data, nodeId, newData) => {
for (let i = 0; i < data.length; i++) {
const item = data[i];
if (item.value === nodeId) {
item.children.push(newData);
break;
} else if (item.children && item.children.length > 0) {
addDataToNode(item.children, nodeId, newData);
}
}
};
const newNodeData = {
title: value,
value: Math.random().toString(36).substr(2, 9),
children: []
};
addDataToNode(newData, node, newNodeData);
setTreeData(newData);
setIsModalOpenForm(false);
setBasicData({ ...data, nodeId: randomId });
};
return(
<div>
<ProjectComponets onSave={handleSave} />
<TreeSelect {...tProps} onSelect={onSelect} treeData={treeData} />
<FormComponets
visible={isModalOpenForm}
onClose={handleCloseModal}
onSave={(data, value, node, updateTreeData) => FormSave(data, value, node, updateTreeData)}
treeData={treeData}
updateTreeData={setTreeData} // 将 setTreeData 函数作为 updateTreeData 参数传递给 FormComponets
/>
<BasicDrawer visible={isModalOpenBaic} basicData={basicData}/>
</div>
);
;
}
export default TreeComponets;
父组件中实现点击那个+号标签的时候输入信息然后把数据保存到这个+号标签的节点下面属于在他的节点下新建一个新的节点


上图:
太长了 没看完,反向排查问题
是不是有个treeData console或者debugger一下 先看看这个更新了吗
如果确定更新了 考虑是不是数据结构的问题,可以提交的时候 模拟个最简单的数据结构返回过去看看正常吗
如果还不行,那就不考虑通信,在tree那个组件写个click事件,直接加上一条简单的看看能行不。
到这应该能排查出来问题了我认为
如果还不行,官网demo copy一份下来改吧😂
子组件1通过props调用父组件的方法,父组件通过ref2调用子组件2的方法
子组件2通过props调用父组件的方法,父组件通过ref1调用子组件1的方法