React

自定义 hook —— useSize

2021-11-22  本文已影响0人  Lia代码猪崽

代码

import { useState, useEffect } from 'react'

export const getTargetElement = (target, defaultElement = window) => {
  if (!target) {
    return defaultElement
  }

  let targetElement;

  if (typeof target === 'function') {
    targetElement = target()
  } else if ('current' in target) {
    if (target.current) {
      targetElement = target.current
    } else {
      return defaultElement
    }
  } else {
    targetElement = target
  }

  return targetElement
}

const useSize = (target) => {
  const [state, setState] = useState({
    width: 0,
    height: 0
  })

  useEffect(() => {
    const targetElement = getTargetElement(target) 
    if (!targetElement) {
      return
    }

    const observer = new ResizeObserver(function elResizeChange(entries) {
      // 每次被观测的元素尺寸发生改变这里都会执行
      entries.forEach((entry) => {
        const { width, height } = entry.target.getBoundingClientRect()
        setState({
          width: width,
          height: height,
        });
      });
    })
    observer.observe(targetElement) // 观测DOM元素

    return () => {
      observer.disconnect()
    }
  }, [target])

  return {
    ...state
  }
}

export default useSize

demo

import React, { useRef } from 'react'
import useSize from './hooks/useSize'

function App() {
  const ref = useRef(null);
  const { width, height } = useSize(ref)

  return (
    <div className="App" style={{textAlign: 'right'}}>
      <div ref={ref} style={{ 
        position: 'absolute',
        width: '33%', 
        height: '66%', 
        background: 'pink' 
      }}>
        123213123
      </div>
      <div>{width}</div>
      <div>{height}</div>
    </div>
  );
}

export default App;
image.png
image.png
上一篇 下一篇

猜你喜欢

热点阅读