LoginSignup
14
15

More than 5 years have passed since last update.

ES7 Decoratorでresizeイベントをいい感じに処理してくれるパッケージ作ったよ

Posted at

今、React・Fluxで作っているツールで、window.onresize時にwindow.innerHeightをdivのheightとして設定するようなComponentを作った。

こういう感じ:

class Example extends React.Component {
    constructor (props) {
        super(props);

        this._onWindowResize = this.onWindowResize.bind(this)
        this.setState({ height: 0, width: 0 })
    }

    render () {
        let {width, height} = this.state;
        return <div {...this.props} style={{ width, height }} />;
    }

    onWindowResize () {
        this.setState({
            height: window.innerHeight,
            width: window.innerWidth
        });
    }

    componentDidMount () {
        window.addEventListener('resize', this._onWindowResize);
    }

    componentWillUnmount () {
        window.removeEventListener('resize', this._onWindowResize);
    }
}

「これはES7 DecoratorやHigher-Order Componentで共通化出来そうだ」と思ったので、on-resizeというパッケージを作りました。

使い方

インストール

$ npm install --save on-resize

ES7 Decoratorの場合

import {onResize} from "on-resize/react";

@onResize()
class Example extends React.Component {
    render () {
        // window.onresize時にwidth, heightが渡ってくる
        let {width, height} = this.props;
        return <div {...this.props} style={{ width, height }} />;
    }
}

デフォルトではwindow.onresize時に、window.innerWidth - props.offsetWidthwidthに、window.innerHeight - props.offsetHeightheightに、props経由で渡ってくる。
渡ってくる値とか変数名を変えたい場合は、@onResizeに引数として渡せば変更できる。

@onResize((props) => ({
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight
}))

// OR

@onResize({
    select: (props) => ({
        innerWidth: window.innerWidth,
        innerHeight: window.innerHeight
    }
})

Higher-Order Componentの場合

Decoratorとほとんど一緒。bindOnResizeをimport(require)して使う

import {bindOnResize} from "on-resize/react";

class Example extends React.Component {
    render () {
        // window.onresize時にwidth, heightが渡ってくる
        let {width, height} = this.props;
        return <div {...this.props} style={{ width, height }} />;
    }
}

// ラップしたComponentを返す
export default bindOnResize(Example);

挙動の変更もDecoratorと一緒。

bindOnResize(Component, (props) => ({
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight
}))

// OR

bindOnResize(Component, {
    select: (props) => ({
        innerWidth: window.innerWidth,
        innerHeight: window.innerHeight
    }
})

まとめ

  • ES7 Decorator、最初きもいなーと思ったけど使うと便利
  • インターフェースはreduxを結構参考にしている
    • 今後React以外にも対応できるようにon-resize/reactにしたりとか
  • テスト書くの面倒なので、ちょっとしか書いてない。書かねば。

何かバグとかあれば、Githubのissueでご連絡くださいー

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15