我正在尝试测量TreeNodes
的DOM位置。我正在使用Ant Design的Tree
组件(我将CSS修改为显示为组织图)。
该指标似乎始终是前一个指标,而不是当前指标。 唯一正确的位置是第一次渲染树。
这里是repository,可以看到它的运行情况:
我遵循了React文档中的useCallback
example。
我在array
函数中尝试了许多不同的选项作为第二个参数useLayoutEffect
。 唯一更新坐标的参数是省略第二个参数,但这会导致无限循环。
import * as React from "react";
import { useCallback, useLayoutEffect, useState } from "react";
export interface TreeNodeProps {
id: string;
nodeData: any;
coordinates?: ClientRect;
}
export const TreeNode: React.FC<TreeNodeProps> = props => {
const { id, nodeData } = props;
const [domElement, setDomElement] = useState<HTMLElement>(undefined);
const [coordinates, setCoordinates] = useState<ClientRect>({
left: 0,
right: 0,
bottom: 0,
top: 0,
height: 0,
width: 0
});
const nodeRef = useCallback((node: HTMLElement) => {
if (node !== null) {
setDomElement(node);
setCoordinates(node.getBoundingClientRect());
}
}, []);
// I tried many combinations for the second argument here
// the only one that always update is no argument at all so the hook
// runs in an infinite loop.
useLayoutEffect(() => {
domElement &&
setCoordinates(roundDecimals(domElement.getBoundingClientRect()));
console.log(props.nodeData.title, JSON.stringify(coordinates, null, 2));
}, [
domElement,
domElement && domElement.getBoundingClientRect().left,
domElement && domElement.getBoundingClientRect().bottom,
domElement && domElement.getBoundingClientRect().right
]);
const wbsId = (nodeData && nodeData.wbsId) || "wbsId";
const title = (nodeData && nodeData.title) || "title";
return (
<div ref={nodeRef} id={id} className={styles.treeNode}>
<p style={{ margin: 0 }}>
{wbsId} {title}
</p>
<div style={{ display: "inline-flex" }}>
<ul style={{ margin: 0 }}>
<li>left: {coordinates.left}</li>
<li>right: {coordinates.right}</li>
</ul>
<ul style={{ margin: 0 }}>
<li>bottom: {coordinates.bottom}</li>
<li>top: {coordinates.top}</li>
</ul>
<ul style={{ margin: 0 }}>
<li>height: {coordinates.height}</li>
<li>width: {coordinates.width}</li>
</ul>
</div>
</div>
);
};