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
相关产品推荐
相关产品推荐

