ahooks源码分析-useSize

1,259 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

今天开始一起学习分享 ahooks 的源码

ahooks是阿里巴巴出品的一套高质量可靠的 React Hooks 库

今天分享 第9个 hooks-useSize

useSize

首先看下 useSize 的作用是什么

useSize 的作用是监听 DOM 节点尺寸变化的 Hook。

接下来 看下 API

API

const size = useSize(target);

Params

参数表示 目标元素的 dom节点 或者 ref

参数说明类型默认值
targetDOM 节点或者 refElement | (() => Element) | MutableRefObject<Element>-

Result

结果返回 目标元素dom节点的尺寸,包括width和height

参数说明类型
sizeDOM 节点的尺寸{ 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>
  );
};

image.png

传入 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>
  );
};

image.png

接下来一起看下 源码

源码

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

其他hooks

useLatest

useEventListener

useClickAway

useDocumentVisibility

useTitle