我试图用ReactJS从JSON数据中实现树视图,我完成了大部分工作但是我的扩展和折叠按钮有问题。正如现在单击其中一个子树节点成功扩展整个树时,问题是根据组件的状态(折叠/展开)我想更改图标。有人能帮助我吗?
import React from 'react';
import {IconExpand, IconCollapse} from '../components/Icons';
export default class Tree extends React.Component{
constructor(props){
super(props);
const me = this;
me.state = {
visible: true
};
me.listItem = null;
me.isVisible = me.isVisible.bind(me);
}
render(){
const me = this;
const {visible} = me.state;
const {jsonData} = me.props;
let keys = [];
for (const key in jsonData) {
if (jsonData.hasOwnProperty(key)) {
keys.push(key);
}
}
return (
<ul className="x-tree">
{keys.map((key, index) => {
if(jsonData[key] && typeof jsonData[key] === 'object'){
return (
<li
className="x-tree-item x-tree-item-node"
key={`complex-${key}-${index}`}
ref={el => { me.listItem = el; }}
>
{visible
? <IconCollapse
className="x-tree-icon"
/>
: <IconExpand
className="x-tree-icon"
/>
}
<span
className="x-tree-key"
onClick={me.onClick.bind(me)}
>
{key}
</span>
<Tree
jsonData={jsonData[key]}
expanded={true}
/>
</li>
)
} else {
return (
<li
className="x-tree-item"
key={`simple-${key}-${index}`}
>
<span className="x-tree-key">{key}: </span>
<span className="x-tree-value"> {jsonData[key]}</span>
</li>
)
}
})}
</ul>
);
}
onClick(event){
const me = this;
let node = event.currentTarget;
let tree = node.nextSibling;
tree.style.display = tree.style.display === 'none' ? 'block' : 'none';
me.setState({
visible: !me.state.visible
});
me.isVisible(tree.style.display !== 'none');
}
isVisible(key){
return key;
}
}
答案 0 :(得分:1)
有些事情是这样的:
class Tree extends React.Component{
constructor(props){
super(props);
const me = this;
me.state = {selected: (new Map(): Map<string, boolean>)};
me.listItem = null;
}
render(){
const me = this;
const {visible} = me.state;
const {jsonData} = me.props;
let keys = [];
for (const key in jsonData) {
if (jsonData.hasOwnProperty(key)) {
keys.push(key);
}
}
return (
<ul className="x-tree">
{keys.map((key, index) => {
if(jsonData[key] && typeof jsonData[key] === 'object'){
return (
<li
className="x-tree-item x-tree-item-node"
key={`complex-${key}-${index}`}
ref={el => { me.listItem = el; }}
>
<span
className="x-tree-key"
onClick={me.onClick.bind(me)}
id={key}
>
{!!me.state.selected.get(key)
? <IconCollapse
className="x-tree-icon"
/>
: <IconExpand
className="x-tree-icon"
/>
}
{key}
</span>
<Tree
jsonData={jsonData[key]}
expanded={true}
/>
</li>
)
} else {
return (
<li
className="x-tree-item"
key={`simple-${key}-${index}`}
>
<span className="x-tree-key">{key}: </span>
<span className="x-tree-value"> {jsonData[key]}</span>
</li>
)
}
})}
</ul>
);
}
onClick(event){
const me = this;
let node = event.currentTarget;
let tree = node.nextSibling;
console.log(node.id);
tree.style.display = tree.style.display === 'none' ? 'block' : 'none';
this.setState((state) => {
const selected = new Map(state.selected);
selected.set(node.id, !selected.get(node.id)); // toggle
return {selected};
});
}
}
答案 1 :(得分:0)
你应该为每个节点添加一个状态,因为它现在是整个树的visible
状态
树组件的所有节点都具有相同的表达式
{visible ? <IconCollapse className="x-tree-icon" /> : <IconExpand className="x-tree-icon" /> }
并且表达式visible对于每个<li>
节点具有相同的值,因此您的组件对于特定树级别中的所有节点都有一个状态visible
。