主动计算宽高的 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
🐠 往期水文
不必递归生成有限层级的树
基于qiankun微前端实战部署
发表回复