如何使用 javascript 显示具有父子关系的数据?

问题描述 投票:0回答:1
const data = [
    { id: 1, text: 'hello', parent: null },
    { id: 2, text: 'hello2', parent: 1 },
    { id: 3, text: 'hello3', parent: 2 },
    { id: 4, text: 'where are u?', parent: null },
  ];
  function convertToTree(data: any) {
    const tree: any = {};
    data.forEach((item: any) => {
      const parentId = item.parent;
      if (!parentId) {
        tree[item.id] = { ...item, children: [] };
      } else {
        if (!tree[parentId]) {
          tree[parentId] = { children: [] };
        }
        tree[parentId].children.push({ ...item, children: [] });
      }
    });
    return tree;
  }

  function TreeNode({ data }: any) {
    const [isVisible, setIsVisible] = useState(false);

    const handleClick = () => {
      setIsVisible(!isVisible);
    };

    return (
      <div>
        <p onClick={handleClick}>{data.text}</p>
        {isVisible && data.children && data.children.length > 0 && (
          <ul>
            {data.children.map((child: any) => (
              <li key={child.id}>
                <TreeNode data={child} />
              </li>
            ))}
          </ul>
        )}
      </div>
    );
  }

我想根据使用 javascript-react 的数据中的父数据将此数据显示为父子数据。

  • 规则#1:当我单击父数据时,我想查看子数据。
  • 规则#2:由于每个孩子也可以是父母,如果孩子有孩子数据,我想在单击孩子时访问其自己的孩子数据。

但是在我写的代码中,只有当我点击父数据时,才只有子数据来。正如数据中所示,子数据也有子数据,但我看不到它们。

谢谢您的帮助

javascript reactjs typescript
1个回答
1
投票

这就是我所拥有的,基本上是递归地将节点添加到树然后打印它的方法

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
        items: [
    { id: 1, text: 'hello', parent: null },
    { id: 2, text: 'hello2', parent: 1 },
    { id: 3, text: 'hello3', parent: 2 },
    { id: 4, text: 'where are u?', parent: null },
      ]
    }
  }
  
  transformToTree(data) {
    const tree = {};
    
    //elems that have a parent but not in tree
    const invisibleParents = {};
    for(let node in data.items)
    {
        if (!node.parent)
      {
        //first node of tree
        tree[node.id] = {...node, children: []};
        
        if (node.id in invisibleParents)
        {
            tree[node.id].children.push(...invisibleParents[node.id]);
            delete invisibleParents[node.id];
        }
        
        continue;
      }
      
      if (node.parent in tree)
      {
        //directly add
        tree[node.parent].children.push(node);
      }
      else
      {
        if (node.parent in invisibleParents)
            invisibleParents[node.parent].push(node);
        else
            invisibleParents[node.parent] = [node];
      }
    }
    
    return tree;
  }
  
  render() {
  const treeData = transformData(this.state.data);
    return (
        treeData.map(x => 
        {
            return (<SmallComponent item={x} />)
        })
    )
  }
}

class SmallComponent extends React.Component
{
  constructor(props)
  {
    super(props);
    this.state = {...props};
  }
  
    render() {
  item = this.state.item;
  return (
  <div>
      <p>
        {item.text}
        {item.children.length && 
        <ul>
          <li>
            {item.children.map(x => 
            (
                <SmallComponent item={x} />
            ))}
          </li>  
        </ul>}
      </p>
    </div>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))

© www.soinside.com 2019 - 2024. All rights reserved.