javascript - TreeView - 检查是否展开并单击

标签 javascript reactjs

我正在使用 Material UI 中的 Treeview 组件构建一个 TreeView:https://material-ui.com/components/tree-view/

我创建了一个组件,当节点展开时,该组件会在下面获取数据。此外,树的构建使得每个有子节点的节点也是一棵树,但我有两个问题:

问题 1: 现在,每次展开节点时都会调用 fetchChildNodes。我想更改此设置,以便检查当前节点之前是否已扩展。如果它已展开,我不想调用 fetchChildNodes,而是使用之前获取的数据。这是因为我对于一个节点可以展开、关闭、再展开,而fetchChildNodes会在这个过程中被调用两次。我怎样才能检查这个?

问题 2: 是否有某种 onClick 方法可以为单击的节点提供 nodeIdexpandingNodes 仅为可扩展节点提供 nodeId,而不为 leaf 节点提供。

import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
const { useState, useCallback } = React;

export default function MyTreeItem(props) {
  const [childNodes, setChildNodes] = useState(null);
  const [expanded, setExpanded] = React.useState([]);

  function fetchChildNodes(id) {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve({
          children: [
            {
              id: "2",
              name: "Calendar"
            },
            {
              id: "3",
              name: "Settings"
            },
            {
              id: "4",
              name: "Music"
            }
          ]
        });
      }, 1000);
    });
  }

  const handleChange = (event, nodes) => {
    const expandingNodes = nodes.filter(x => !expanded.includes(x));
    setExpanded(nodes);
    if (expandingNodes[0]) {
      const childId = expandingNodes[0];
      fetchChildNodes(childId).then(result =>
        setChildNodes(
          result.children.map(node => <MyTreeItem key={node.id} {...node} />)
        )
      );
    }
  };

  return (
    <TreeView
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
      expanded={expanded}
      onNodeToggle={handleChange}
    >
      {/*The node below should act as the root node for now */}
      <TreeItem nodeId={props.id} label={props.name}>
        {childNodes || [<div key="stub" />]}
      </TreeItem>
    </TreeView>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyTreeItem id="1" name="Applications" />, rootElement);

最佳答案

回答问题2:

只需将自定义标签对象添加到 TreeItem :

import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
const { useState, useCallback } = React;

export default function MyTreeItem(props) {
  const [childNodes, setChildNodes] = useState(null);
  const [expanded, setExpanded] = React.useState([]);

  function fetchChildNodes(id) {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve({
          children: [
            {
              id: "2",
              name: "Calendar"
            },
            {
              id: "3",
              name: "Settings"
            },
            {
              id: "4",
              name: "Music"
            }
          ]
        });
      }, 1000);
    });
  }

  const handleChange = (event, nodes) => {
    const expandingNodes = nodes.filter(x => !expanded.includes(x));
    setExpanded(nodes);
    if (expandingNodes[0]) {
      const childId = expandingNodes[0];
      fetchChildNodes(childId).then(result =>
        setChildNodes(
          result.children.map(node => (
            <MyTreeItem key={node.id} {...node}  />
          ))
        )
      );
    }
  };

  const renderLabel = item => (
    <span
      onClick={event => {
        console.log(item.id);
        //setActiveItemId(item.id);
        // if you want after click do expand/collapse comment this two line
        event.stopPropagation();
        event.preventDefault();
      }}
    >
      {item.name}
    </span>
  );

  return (
    <TreeView
      defaultCollapseIcon={<ExpandMoreIcon />}
      defaultExpandIcon={<ChevronRightIcon />}
      expanded={expanded}
      onNodeToggle={handleChange}
    >
      {/*The node below should act as the root node for now */}
      <TreeItem nodeId={props.id} label={renderLabel(props)}>
        {childNodes || [<div key="stub" />]}
      </TreeItem>
    </TreeView>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(
  <MyTreeItem id="1" name="Applications" />,
  rootElement
);

onclick screenshot

关于javascript - TreeView - 检查是否展开并单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59490963/

相关文章:

javascript - 使用从父页面到 iframe 的跳转链接

javascript - ionic 3 angular chartjs Canvas 在显示隐藏时消失

javascript - React 无法获取数组的长度

javascript - 在 Ant.Design 中个性化 ReactJS 分页样式 - 有什么办法吗?

javascript - 如何在 Javascript 中返回具有特定条件的对象数组?

javascript - 如何将对象中的键值对转换为对象数组?

javascript - 如何将数组中的所有 onNext 值放在一起?

reactjs - Material-ui 网格响应方向列宽度不起作用

javascript - 使用转义的 html 字符 react 渲染变量

reactjs - 在另一个组件 V6 中 react 路由