响应MouseEnter事件。currentTarget始终为null

问题描述 投票:0回答:1

我正在使用带有自定义节点元素的 React d3 树。我试图在悬停节点时显示一些文本,但它仅在我第一次悬停在一个节点上时有效,然后每次悬停节点时 mouse.currentTarget 似乎为空,因此 Documentation.show 不会设置为真的。 使用 useMemo 以便每次我将鼠标悬停在节点上时整个组件不会重新渲染(因为文档状态发生变化)。

import Tree, { TreeNodeDatum } from "react-d3-tree";

const [documentation, setDocumentation] = useState({
    x: 0,
    y: 0,
    show: false,
    text: "test text.",
  });

const TreeMemo = useMemo(() => {

    const renderCustomNode = ({
      nodeDatum,
      toggleNode,
    }: {
      nodeDatum: TreeNodeDatum;
      toggleNode: () => void;
    }) => (
      <g>
        <circle
          r="15"
          onMouseEnter={(mouse) =>
            setDocumentation((prevState) => {
              return mouse.currentTarget
                ? {
                    x:
                      mouse.clientX -
                      mouse.currentTarget.getBoundingClientRect().right,
                    y:
                      mouse.clientY -
                      mouse.currentTarget.getBoundingClientRect().top,
                    show: true,
                    text: prevState.text,
                  }
                : prevState;
            })
          }
          onMouseLeave={() => {
            setDocumentation((prevState) => {
              return {
                ...prevState,
                show: false,
              };
            });
          }}
          onClick={toggleNode}
        />
        <text fill="black" strokeWidth="1" x="20">
          {nodeDatum.name}
        </text>
        {nodeDatum.attributes?.department && (
          <text fill="black" x="20" dy="20" strokeWidth="1">
            Department: {nodeDatum.attributes?.department}
          </text>
        )}
      </g>
    );
    
    return (
      <Tree
        key={triggerRecenter}
        data={orgChart}
        translate={treeTranslate}
        dimensions={
          treeContainerRef.current
            ? {
                height: treeContainerRef.current.getBoundingClientRect().height,
                width: treeContainerRef.current.getBoundingClientRect().width,
              }
            : undefined
        }
        renderCustomNodeElement={(rd3tProps) =>
          renderCustomNode({ ...rd3tProps })
        }
        orientation="vertical"
      />
    );
  }, [triggerRecenter, treeTranslate]);

在 useMemo deps 中添加文档状态使其可以工作,但会触发整个组件的重新渲染,这是不需要的。 还使用 onMouseMove 似乎有效,但它使位置发生变化。

javascript reactjs d3.js react-hooks
1个回答
0
投票

通过将 onMouseEnter 处理程序更改为下面来解决。根据我的理解,这似乎阻止了 currentTarget 为空,如果我错了请纠正我。

     onMouseEnter={(event) => {
        const { clientX, clientY, currentTarget } = event;
        const { right, top } = currentTarget.getBoundingClientRect();

        setDocumentation((prevState) => {return {
          x: clientX - right,
          y: clientY - top,
          show: true,
          text: prevState.text,
        }});
      }}
© www.soinside.com 2019 - 2024. All rights reserved.