自动计算宽高的 react 组件
github地址:https://github.com/niexq/reac... 欢迎 Star
🏠 主页预览
📦 安装
yarn add @oyyds/react-auto-sizer # or npm i @oyyds/react-auto-sizer -S
🔨 使用
import AutoSizer from '@oyyds/react-auto-sizer';
const AutoSizeComponent = () => {
return (
<div>
<AutoSizer>
{({ width, height }) => (
<div
style={{
width,
height,
}}
>
内容区
</div>
)}
</AutoSizer>
</div>
);
};
🧩 业务场景
现在大部分业务场景需要兼容大数据,例如大数据表格,大数据树,大数据下拉框
等等,而所有的大数据组件都需要指定 宽高
,实际业务界面大部分需要实时计算宽高,而 react-auto-sizer
就是来完成自动计算宽高的使命
。
🧑💻 编码实现
期初预研 windows
上绑定 resize
,但因 resize
会在窗体变化时,会有性能问题,部分极端像素情况下会出现抖动;
ResizeObserver,接口可以监听到 Element
的内容区域或 SVGElement
的边界框改变。内容区域则需要减去内边距padding。 -- 摘自 MDN
ResizeObserver
天选之子, 使用 react hook useEffect
,核心代码如下:
const updateState = useCallback(
(newWidth: number, newHeight: number, entry: ResizeObserverEntry) => {
// 省略更新state
// 回调传入 width, height
props.onResize({ width: newWidth, height: newHeight }, entry);
},
[childParams, disableHeight, disableWidth, onResize],
);
const observer = useMemo(
() =>
new ResizeObserver((entries: ResizeObserverEntry[]) => {
for (const entry of entries) {
const contentRect = entry.contentRect;
const width = Math.trunc(contentRect?.width || 0);
const height = Math.trunc(contentRect?.height || 0);
updateState(width, height, entry);
}
}),
[updateState],
);
useEffect(() => {
if (!_autoSizerRef?.current?.parentNode) {
throw new Error('Not Found AutoSizer parentNode');
}
observer.observe(_autoSizerRef?.current?.parentNode as Element);
return () => {
observer.disconnect();
};
}, [observer]);
重点:
observer.observe(_autoSizerRef?.current?.parentNode as Element)
,监听父级dom节点
contentRect
: ResizeObserverEntry
返回一个DOMRectReadOnly
的只读属性contentRect
, 包含观察元素的新大小的对象,属性:
{
"x": 0,
"y": 0,
"width": 300,
"height": 200,
"top": 0,
"right": 300,
"bottom": 200,
"left": 0
}
contentRect返回是content box,也就是内容区域的尺寸(详细原因可参考张鑫旭大佬的ResizeObserver简介)
所以 contentRect.width
、contentRect.height
就是我们最终需要的宽高
🐳 灵感来源
react-virtualized-auto-sizer
ResizeObserver
检测DOM尺寸变化JS API ResizeObserver
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。