🙆
【React / useRef】要素の位置、大きさを取得する
はじめに
ReactでHTML要素の大きさ(幅、高さ)、位置を取得したい場面があり、そのときの実装メモ。
※ TypeScript を使っています
実装
カスタムフックを作る
// 引数のtargetProperty をDOMRectのもつPropertyに限定する
type DOMRectProperty = keyof Omit<DOMRect, 'toJSON'>;
// RefObjectの型は div, span, p, input などのさまざまなHTML要素に対応できるようにextendsで制限をかけつつ抽象化
export const useGetElementProperty = <T extends HTMLElement>(
elementRef: RefObject<T>
) => {
const getElementProperty = useCallback(
(targetProperty: DOMRectProperty): number => {
const clientRect = elementRef.current?.getBoundingClientRect();
if (clientRect) {
return clientRect[targetProperty];
}
// clientRect が undefined のときはデフォルトで0を返すようにする
return 0;
},
[elementRef]
);
return {
getElementProperty,
};
};
offsetxx と getBoundingClientRect().xx の違い
この書き方でも width を取得できる
elementRef.current?.offsetWidth;
- getBoundingClientRect().xx: 小数値を含む数値
- offsetxx: 値を整数に丸めた数値
補足
↓これは
type DOMRectProperty = keyof Omit<DOMRect, 'toJSON'>;
↓これと同じこと
type DOMRectProperty =
| 'height'
| 'width'
| 'x'
| 'y'
| 'top'
| 'right'
| 'bottom'
| 'left';
Componentで利用する
カスタムフックを呼び出して利用する。
const Home: NextPage = () => {
const targetRef = useRef(null);
const { getElementProperty } =
useGetElementProperty<HTMLDivElement>(targetRef);
return (
<div>
{/*値を取得したい要素にRefをセットする*/}
<div ref={targetRef}>
{/*~~~~~~省略~~~~~~*/}
</div>
</div>
取得した値をコンソールに出力してみる
const Home: NextPage = () => {
const targetRef = useRef(null);
const { getElementProperty } =
useGetElementProperty<HTMLDivElement>(targetRef);
useEffect(() => {
console.log("height", getElementProperty("height"));
console.log("width", getElementProperty("width"));
console.log("x", getElementProperty("x"));
console.log("y", getElementProperty("y"));
console.log("top", getElementProperty("top"));
console.log("right", getElementProperty("right"));
console.log("bottom", getElementProperty("bottom"));
console.log("left", getElementProperty("left"));
}, []);
return (
<div>
{/*値を取得したい要素にRefをセットする*/}
<div ref={targetRef}>
{/*~~~~~~省略~~~~~~*/}
</div>
</div>
取得できた!
最後に
ありがとうございました!!
Discussion