LoginSignup
8
4

More than 5 years have passed since last update.

Reactコンポーネントのスタイルを切り替えるにはどうしたらいいですか?

Last updated at Posted at 2017-06-14

これは「コードを書いていて困ったときに、suinがチャットで質問に答えたり相談に乗るsuinのプログラミング相談室(仮)」で頂いた質問と僕の回答の要約です。

質問

Reactで同じコンポーネントに違うスタイルを当てるにはどのようにしたらいいですか? ABテストを考えていて、ある条件ではスタイルAを、別の条件ではスタイルBを当てられるようにしたいです。

suinの回答

CSSで解決する方法と、Reactで解決する方法の2つが考えられます。

CSSで解決する方法

例えば、ReactのAppモジュールではappクラスを決め打ちにしておいて、ReactがレンダリングされるDOMをclass="red"class="blue"で囲めば、.red .app.blue .appでそれぞれ別のスタイルが適用できます。React外の技術でアプローチするパターンですね。

<div class="red">
    <div id="root"></div>
</div>

<div class="blue">
    <div id="root"></div>
</div>
class App extends React.Component {
    render () {
        return <div className="app">App!</div>
    }
}

ReactDOM.render(<App />, document.getElementById('root'))
.red .app {
    color: red;
}

.blue .app {
    color: blue;
}

Reactで解決する方法

Reactでやる場合は、コンポーネントの設定値をコンポーネント使う側から渡せるようにします。

class App extends React.Component {
    // 属性情報のバリデーション
    static propTypes = {
        taste: React.PropTypes.string.isRequired
    }

    // 親からXML属性で受け取れるようにする
    constructor (props) {
        super(props)
        this.state = {...なにかあれば...}
    }

    render () {
        console.log(this.props) // ここで taste 属性があるはず

        // ここでスタイルを切り替える
        const className = this.props.taste === 'red' ? 'red-app' : 'blue-app'

        // たしかこれでいいはず
        return <div className={className}>App!</div>
    }
}

// コンポーネントを使う側
ReactDOM.render(<App taste="red" />, document.getElementById('red-app'))
ReactDOM.render(<App taste="blue" />, document.getElementById('blue-app'))
<div id="red-app"></div>
<div id="blue-app"></div>
.red-app {
    color: red;
}

.blue-app {
    color: blue;
}

PHP(サーバサイド)側で動的にスタイルを指定する場合

ちなみに、サーバサイドでスタイルを動的に指定する場合はこうです。まず、PHP側では動的にdata-tasteを書き出すようにします。

<?php
$taste = $someCondition ? 'red' : 'blue';
echo '<div id="app" data-taste="' . $taste . '"></div>';

サーバサイドのロジックによって

<div id="app" data-taste="red"></div> 

などが描画されます。

JSではそれを受け取れるようにします。

main.js
const element = document.getElementById('#app')

console.log(element.dataset)
console.log(element.dataset.taste) // あるはず

const dataset = JSON.parse(JSON.stringify(element.dataset)); // Object.assignがSafariではうまくいかないため
ReactDom.render(<App {...dataset} />, element);

ちなみにこのテクは、僕が作ったQiita Widgetで使っています。このへんのコードです→https://github.com/suin/qiita-widget/blob/master/src/main.js#L10

回答に対しての反応

おお、今か書いて下さったdatasetで切り替えるのが良さそうです! Safariでダメなのも知らなかったです。

8
4
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
8
4