Posted at

reactでDOM要素のサイズを知りたい

More than 1 year has passed since last update.

react-measureを使う


背景



  • svgタグやcanvasタグ等で、widthheight属性を設定したい

  • けれど、それらをレンダリングする場所は、固定サイズでないため(CSSでwidth: 100%等)レンダリングするまで具体的なサイズが不明

  • そのほか、コンテナー要素のサイズに応じて、自前でレイアウト計算したいことがある


解決策



  • react-measureのコンポーネントのchildrenでサイズを計測したい要素をレンダリングする

  • childrenとしてFunctionを設定すると、measureRef(サイズ計測対象のrefをreact-measeureに渡すためのもの)が引数で渡されてくる

  • サイズ計測したい要素のrefmeasureRefを設定する。


SVGで指定の間隔の罫線を描くコンポーネント。DIV(.grid-inner)のサイズを計測し、その中にDIVと同サイズのSVGを生成し、SVGで罫線を描く


  • 要素のサイズはstateで持つ

  • サイズ変化時にonResize: (contentRect) => voidが呼ばれる。contentRectに計測したサイズが入ってくるので、サイズをsetStateして再レンダリングさせる


import * as React from "react";
import _ = require("underscore");
import Measure from "react-measure";

export interface GridProps {
size: number;
}

export class Grid extends React.Component<GridProps, {}> {
state = {
width: 0,
height: 0
}

render() {
const { size } = this.props;
const { width, height } = this.state;
return <div className="grid">
<Measure bounds onResize={(contentRect) => { this.setState({ ...contentRect.bounds }) }}>
{({ measureRef }) =>
<div ref={measureRef} className="grid-inner">
<svg width={width} height={height}>
<g>
{_.range(size, height, size).map((y) => {
return <line x1={0} y1={y}
x2={width} y2={y}
className="grid-line" />
})}
</g>
</svg>
</div>
}
</Measure>
</div>
}
}

.grid {

width: 100%;
height: 100%;
}

.grid-inner {
width: 100%;
height: 100%;
}