主动计算宽高的 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微前端实战部署