You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-D3-Tree自定义节点hover时仅显示对应悬浮div的实现方案

解决react-d3-tree自定义节点悬停时所有div同步显示的问题

问题出在你使用了全局共享的show状态,所有自定义节点组件都会读取这个状态值,导致只要有一个节点触发悬停,所有节点的div都会切换显示状态。下面提供两种可行的解决方式:

方式一:让每个自定义节点独立维护悬停状态

把自定义节点抽成一个独立的带状态组件,每个节点自己管理是否被悬停的状态,彼此互不干扰:

import { useState } from 'react';

const CustomNode = ({ nodeDatum, toggleNode }) => {
  // 每个节点单独维护hover状态
  const [isHovered, setIsHovered] = useState(false);

  return (
    <g>
      <foreignObject x="20" y="20" width="100%" height="100%">
        <div
          className={isHovered ? "tree__div active" : "tree__div"}
        >
          LOREM IPSUM
        </div>
      </foreignObject>
      <circle
        r="15"
        onMouseEnter={() => setIsHovered(true)}
        onMouseLeave={() => setIsHovered(false)}
        onClick={toggleNode}
      />
      <text fill="black" strokeWidth="1" x="20">
        {nodeDatum.name}
      </text>
    </g>
  );
};

// 原渲染函数改为返回这个独立组件
const renderCustomNode = (props) => <CustomNode {...props} />;

方式二:在父组件中跟踪当前悬停的节点ID

如果需要在父组件中获取当前悬停的节点信息,可以在父组件维护一个记录当前悬停节点ID的状态,通过props传递给每个节点,判断当前节点是否是被悬停的那个:

父组件代码片段:

import { useState } from 'react';
import Tree from 'react-d3-tree';

const YourTreeComponent = () => {
  const [hoveredNodeId, setHoveredNodeId] = useState(null);
  // 假设你的树数据已经给每个节点分配了唯一id
  const treeData = [...];

  const renderCustomNode = ({ nodeDatum, toggleNode }) => (
    <g>
      <foreignObject x="20" y="20" width="100%" height="100%">
        <div
          className={hoveredNodeId === nodeDatum.id ? "tree__div active" : "tree__div"}
        >
          LOREM IPSUM
        </div>
      </foreignObject>
      <circle
        r="15"
        onMouseEnter={() => setHoveredNodeId(nodeDatum.id)}
        onMouseLeave={() => setHoveredNodeId(null)}
        onClick={toggleNode}
      />
      <text fill="black" strokeWidth="1" x="20">
        {nodeDatum.name}
      </text>
    </g>
  );

  return <Tree data={treeData} renderCustomNode={renderCustomNode} />;
};

注意:使用方式二时,确保你的nodeDatum包含唯一的id字段,如果没有,需要在构建树数据时手动添加(比如用uuid生成)。

内容的提问来源于stack exchange,提问作者bogdmu00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:52:26