问题
I'm trying to figure out what I'm doing wrong using this Ant Tree component.
I have two components, the PageAdmin I do a get call to get information about what nodes in the tree that should be marked as selected. I receive the data from the server and put it in the array checkedKeys
and send it to the child component as props CustomTree and I can see the props for the CustomTree component are correctly updated, but the nodes in the tree are NOT selected, plus when I selected another node the checkedKeys
array are cleared out and replaced with only the new selected nodes...
Any ideas what is happening?
PageAdmin.js
import React, { Component } from "react";
import TreeMenu from "./TreeMenu";
import CustomTree from "./CustomTree";
import axios from "axios";
import "./PageAdmin.css"
const BASE_URL = "http://localhost:3000"
class PageAdmin extends Component {
constructor(props) {
super(props);
this.state = {
expandedKeys: [],
autoExpandParent: true,
checkedKeys: [],
selectedKeys: [],
treeData: [],
treeID: this.props.match.params.id
}
}
componentDidMount() {
axios
.get(`${BASE_URL}/eclass/all-nodes`)
.then(result => {
this.setState({
treeData: result.data
});
})
if (this.state.treeID) {
console.log("yes we have a treeID")
axios
.get(`${BASE_URL}/eclass/custom/${this.state.treeID}`)
.then(result => {
this.setState({
checkedKeys: result.data.checkedKeys
});
});
}
}
handleCheckChange = (checkedKeys) => {
this.setState({ checkedKeys });
console.log("checkedKeys", checkedKeys)
}
handleSelectChange = (selectedKeys) => {
this.setState({ selectedKeys });
console.log("selectedKeys", selectedKeys)
}
handleExpandChange = (expandedKeys) => {
this.setState({
expandedKeys,
autoExpandParent: false,
});
}
render() {
return (
<div>
<TreeMenu treeID={this.state.treeID} checkedKeys={this.state.checkedKeys} />
<CustomTree
onCheckChange={this.handleCheckChange}
onSelectChange={this.handleSelectChange}
onExpandChange={this.handleExpandChange}
checkedKeys={this.state.checkedKeys}
expandedKeys={this.state.expandedKeys}
selectedKeys={this.state.selectedKeys}
autoExpandParent={this.state.autoExpandParent}
treeID={this.state.treeID}
treeData={this.state.treeData} />
</div>
);
}
}
export default PageAdmin;
CustomTree.js
import React, { Component } from "react";
import { Tree } from 'antd';
import "./CustomTree.css"
import 'antd/dist/antd.css'
const TreeNode = Tree.TreeNode;
class CustomTree extends Component {
constructor(props) {
super(props);
this.state = {}
}
onExpand = (expandedKeys) => {
console.log('onExpand', arguments);
// console.log('expandedKeys', expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
this.props.onExpandChange(expandedKeys)
}
onCheck = (checkedKeys) => {
// console.log('onCheck', checkedKeys);
this.props.onCheckChange(checkedKeys);
}
onSelect = (selectedKeys, info) => {
// console.log('info', info);
// console.log("selectedKeys", selectedKeys)
this.props.onSelectChange(selectedKeys);
}
renderTreeNodes = (data) => {
return data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode {...item} />;
});
}
render() {
return (
<Tree
checkable
onExpand={this.onExpand}
onCheck={this.onCheck}
onSelect={this.onSelect}
checkedKeys={this.props.checkedKeys}
expandedKeys={this.props.expandedKeys}
autoExpandParent={this.props.autoExpandParent}
selectedKeys={this.props.selectedKeys}
>
{this.renderTreeNodes(this.props.treeData)}
</Tree>
);
}
}
export default CustomTree;
回答1:
I found the bug and I would like to share how I solved it.
Before I did first got the tree node data and second I got the information about which nodes was selected. I had to make both request and update the state at the same time, as there are props for each Node (TreeNode) like checked
and halfChecked
that was not updated before, but now working with bellow changes in code.
componentDidMount() {
axios
.get(`${BASE_URL}/eclass/all-nodes`)
.then(allNodes => {
if (this.state.treeID) {
console.log("yes we have a treeID")
axios
.get(`${BASE_URL}/eclass/custom/${this.state.treeID}`)
.then(dataCheckedKeys => {
this.setState({
checkedKeys: dataCheckedKeys.data.checkedKeys,
nameOfTree: dataCheckedKeys.data.nameOfTree,
treeData: allNodes.data
});
});
} else {
this.setState({
treeData: allNodes.data
});
}
})
}
回答2:
Maybe you have to set the property checkedKeys
and checkStrictly
properly.
checkedKeys
: (Controlled) Specifies the keys of the checked treeNodes (PS: When this specifies the key of a treeNode which is also a parent treeNode, all the children treeNodes of will be checked; and vice versa, when it specifies the key of a treeNode which is a child treeNode, its parent treeNode will also be checked. When checkable
and checkStrictly
is true, its object has checked
and halfChecked
property. Regardless of whether the child or parent treeNode is checked, they won't impact each other.
Watch the documentation of antd for more info https://ant.design/components/tree/
来源:https://stackoverflow.com/questions/49016680/why-is-not-tree-checkboxes-checked-in-the-child-component-using-ant-tree-design