持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
今天开始一起学习分享 ahooks 的源码
ahooks是阿里巴巴出品的一套高质量可靠的 React Hooks 库
今天分享 第9个 hooks-useSize
useSize
首先看下 useSize 的作用是什么
useSize 的作用是监听 DOM 节点尺寸变化的 Hook。
接下来 看下 API
API
const size = useSize(target);
Params
参数表示 目标元素的 dom节点 或者 ref
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| target | DOM 节点或者 ref | Element | (() => Element) | MutableRefObject<Element> | - |
Result
结果返回 目标元素dom节点的尺寸,包括width和height
| 参数 | 说明 | 类型 |
|---|---|---|
| size | DOM 节点的尺寸 | { width: number, height: number } | undefined |
接下来 看下 用法
基本用法
useSize 可以接收 ref 参数
这里是使用ref指定dom元素,通过ref获取dom
import React, { useRef } from 'react';
import { useSize } from 'ahooks';
export default () => {
const ref = useRef(null);
const size = useSize(ref);
return (
<div ref={ref}>
<p>Try to resize the preview window </p>
<p>
width: {size?.width}px, height: {size?.height}px
</p>
</div>
);
};
传入 DOM 节点
useSize 可以接收 dom,在 SSR 场景可以传入函数 ()=> dom
import React from 'react';
import { useSize } from 'ahooks';
export default () => {
const size = useSize(document.querySelector('body'));
return (
<div>
<p>Try to resize the preview window </p>
<p>
width: {size?.width}px, height: {size?.height}px
</p>
</div>
);
};
接下来一起看下 源码
源码
1.首先定义 传入的 target 的类型
target: BasicTarget
export type BasicTarget<T extends TargetType = Element> =
| (() => TargetValue<T>)
| TargetValue<T>
| MutableRefObject<TargetValue<T>>;
2.再定义 返回结果的类型
type Size = { width: number; height: number };
3.首先定义初始值,用state表示
const [state, setState] = useRafState<Size>();
4.然后用useIsomorphicLayoutEffectWithTarget监听变化,获取目标元素,如果不存在,则直接返回。使用第三方库ResizeObserver来监听 尺寸的变化,最后再销毁。在监听的过程中,通过entries来获取尺寸,将获取的尺寸通过setState更新width和height
const el = getTargetElement(target);
if (!el) {
return;
}
const resizeObserver = new ResizeObserver((entries) => {
entries.forEach((entry) => {
const { clientWidth, clientHeight } = entry.target;
setState({
width: clientWidth,
height: clientHeight,
});
});
});
resizeObserver.observe(el);
return () => {
resizeObserver.disconnect();
};
5.最后返回state
state