LoginSignup
16
5

More than 5 years have passed since last update.

Reactコンポーネントの動的スタイル更新

Last updated at Posted at 2018-10-26

React.jsでレスポンシブデザインを

React.jsにはコンポーネントという概念が存在します。
複数の仮想DOMをコンポーネントで管理することにより、
オブジェクト指向ライクな設計が可能となります。

しかし、ここで問題があって...
仮想DOMを扱うReact.jsではとてもCSSを扱いづらい。
動的にスタイルを変更しようとすればどうしようとよく迷う。

というわけでReactコンポーネントの動的スタイル更新方法を
共有したいと思います。

State更新でコンポーネントを再描画

まず、仮想DOMの描画処理をMain.jsに記述します。

Main.js
import React,  { Component } from 'react';
import ReactDOM from 'react-dom';
import {ContentBody} from './ContentBody';

class Main extends Component {
    render() {
        return (
            <ContentBody />
        );
    }
}

ReactDOM.render (
    <Main />,
    document.getElementById("root")
);

export default Main;

次に、Windowのサイズが変更された場合にスタイルを動的に変更するプログラムを書いていきます。

ContentBody.js

import React, { Component } from 'react';

let initWindowSize = {};
let initButtonStyles = {};

export class ContentBody extends Component {
    constructor(props) {
        super(props);
        //Stateにはスタイル用にオブジェクトを保持しておく
        this.state = {
            stylesSendButton: {}
        }
    }
    getInitWindowSize(){
        let width = window.innerWidth
        let height = window.innerHeight; 
        initWindowSize = {
            width: width,
            height: height
        }
        initButtonStyles = {
            background: "#f2f2f3",
            border: "none",
            position: "absolute",
            float: "left",
            left: width*0.8,
            bottom: height*0.01,
            outline: 0,
            display: "block",
            width: width*0.225+"px",
            height: width*0.225+"px"
        }
        //特定のスタイルの更新をStateの更新によって行う
        this.setState({stylesSendButton: initButtonSize});
    }
    getWindowSize(){
        let width = window.innerWidth
        let height = window.innerHeight;
        let window_size = {
            width: width,
            height: height
        }
        return window_size;
    }
    ChangeSizeStyles(windowSize){
        let stylesSendButtonChange = {
            background: "#f2f2f3",
            border: "none",
            position: "absolute",
            float: "left",
            left: windowSize.width*0.8,
            bottom: windowSize.height*0.01,
            outline: 0,
            display: "block",
            width: windowSize.width*0.225+"px",
            height: windowSize.width*0.225+"px"
        }
        this.setState({stylesSendButton: stylesSendButtonChange});
    }
    //windowサイズの変更検知のイベントハンドラを設定
    componentWillMount () {
        window.addEventListener('load', () =>{
            this.getInitWindowSize();
        });
        window.addEventListener('resize', () => {
            let window_csize = this.getWindowSize();
            this.ChangeSizeStyles(window_csize);
        });
    }
    render() {
        return (
            <div>
            //StyleをStateで管理できるように設定
                <button id="button" style={this.state.stylesSendButton} />
            </div>
        );
    }
}

以上です。
こっちのほうがスタイルの変更が容易だよとか、
その他、指摘などあればコメントよろしくお願いします。

16
5
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
16
5