获取组件宽高
效果:通过调用 useComponentSize 拿到某个组件 ref 实例的宽高,并且在宽高变化时,rerender 并拿到最新的宽高。
import React, { useLayoutEffect, useState, useRef } from 'react';
function getSize(el) {
if (!el) {
return {};
}
return {
width: el.offsetWidth,
height: el.offsetHeight,
};
}
function useComponentSize(ref) {
const [ComponentSize, setComponentSize] = useState(getSize(ref.current));
function handleResize() {
if (ref && ref.current) {
setComponentSize(getSize(ref.current));
}
}
useLayoutEffect(() => {
handleResize();
let resizeObserver = new ResizeObserver(() => handleResize());
resizeObserver.observe(ref.current);
return () => {
resizeObserver.disconnect(ref.current);
resizeObserver = null;
};
}, []);
return ComponentSize;
}
export default function Demo() {
const ref = useRef(null);
const componentSize = useComponentSize(ref);
return (
<>
{componentSize.width}
<textarea ref={ref} />
</>
);
}
拿到组件 onChange 抛出的值
效果:通过 useInputValue() 拿到 Input 框当前用户输入的值,而不是手动监听 onChange 再腾一个 otherInputValue 和一个回调函数把这一堆逻辑写在无关的地方。
import React, { useState, useCallback } from 'react';
function useInputValue(initialValue) {
const [value, setValue] = useState(initialValue);
const onChange = useCallback(function(e) {
setValue(e.currentTarget.value);
}, []);
return {
value,
onChange,
};
}
export default function Demo() {
const name = useInputValue('jjsun');
return (
<>
{name.value}
<input {...name} />
</>
);
}