読者です 読者をやめる 読者になる 読者になる

IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

ReactでHTMLの共通化

SBAdmin2のダッシュボードページにあるカードのUI部分をReactにて共通化してみました。

startbootstrap.com

ここの部分です。

f:id:naotoogawa:20170326160605p:plain

下記が4枚あるカードのコードになります。これをReactを使って共通化します。背景色と表示内容だけが異なり、タグの構造は全く同じです。

            <div class="row">
                <div class="col-lg-3 col-md-6">
                    <div class="panel panel-primary">
                        <div class="panel-heading">
                            <div class="row">
                                <div class="col-xs-3">
                                    <i class="fa fa-comments fa-5x"></i>
                                </div>
                                <div class="col-xs-9 text-right">
                                    <div class="huge">26</div>
                                    <div>New Comments!</div>
                                </div>
                            </div>
                        </div>
                        <a href="#">
                            <div class="panel-footer">
                                <span class="pull-left">View Details</span>
                                <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                                <div class="clearfix"></div>
                            </div>
                        </a>
                    </div>
                </div>
                <div class="col-lg-3 col-md-6">
                    <div class="panel panel-green">
                        <div class="panel-heading">
                            <div class="row">
                                <div class="col-xs-3">
                                    <i class="fa fa-tasks fa-5x"></i>
                                </div>
                                <div class="col-xs-9 text-right">
                                    <div class="huge">12</div>
                                    <div>New Tasks!</div>
                                </div>
                            </div>
                        </div>
                        <a href="#">
                            <div class="panel-footer">
                                <span class="pull-left">View Details</span>
                                <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                                <div class="clearfix"></div>
                            </div>
                        </a>
                    </div>
                </div>
                <div class="col-lg-3 col-md-6">
                    <div class="panel panel-yellow">
                        <div class="panel-heading">
                            <div class="row">
                                <div class="col-xs-3">
                                    <i class="fa fa-shopping-cart fa-5x"></i>
                                </div>
                                <div class="col-xs-9 text-right">
                                    <div class="huge">124</div>
                                    <div>New Orders!</div>
                                </div>
                            </div>
                        </div>
                        <a href="#">
                            <div class="panel-footer">
                                <span class="pull-left">View Details</span>
                                <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                                <div class="clearfix"></div>
                            </div>
                        </a>
                    </div>
                </div>
                <div class="col-lg-3 col-md-6">
                    <div class="panel panel-red">
                        <div class="panel-heading">
                            <div class="row">
                                <div class="col-xs-3">
                                    <i class="fa fa-support fa-5x"></i>
                                </div>
                                <div class="col-xs-9 text-right">
                                    <div class="huge">13</div>
                                    <div>Support Tickets!</div>
                                </div>
                            </div>
                        </div>
                        <a href="#">
                            <div class="panel-footer">
                                <span class="pull-left">View Details</span>
                                <span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
                                <div class="clearfix"></div>
                            </div>
                        </a>
                    </div>
                </div>
            </div>

まず、ライブラリを取り込みます。

    <!-- React.js -->
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

カードのHTML部分はdiv要素のみにします。

            <div class="row">
                <div id="card1"></div>
                <div id="card2"></div>
                <div id="card3"></div>
                <div id="card4"></div>
            </div>

カードのコードはJSXで書き直します。class属性はclassName属性に書き換えます。そして、カードごとに異なる部分はパラメータとします。{}で囲った部分に値を埋め込みます。

function getCard(prop) {
return <div className="col-lg-3 col-md-6">
    <div className={prop.mainStyle}>
        <div className="panel-heading">
            <div className="row">
                <div className="col-xs-3">
                    <i className="fa fa-comments fa-5x"></i>
                </div>
                <div className="col-xs-9 text-right">
                    <div className="huge">{prop.num}</div>
                    <div>{prop.text}</div>
                </div>
            </div>
        </div>
        <a href="#">
            <div className="panel-footer">
                <span className="pull-left">View Details</span>
                <span className="pull-right"><i className="fa fa-arrow-circle-right"></i></span>
                <div className="clearfix"></div>
            </div>
        </a>
    </div>
</div>;
}

共通化したコードに実引数を与えて、先ほど定義したdiv要素と関連付けさせます。

ReactDOM.render(
  getCard({num : 26, text : "New Comments!", mainStyle : "panel panel-primary"}),
  document.getElementById('card1')
)
ReactDOM.render(
  getCard({num : 12, text : "New Tasks!", mainStyle : "panel panel-green"}),
  document.getElementById('card2')
)
ReactDOM.render(
  getCard({num : 124, text : "New Orders!", mainStyle : "panel panel-yellow"}),
  document.getElementById('card3')
)
ReactDOM.render(
  getCard({num : 13, text : "Support Tickets!", mainStyle : "panel panel-red"}),
  document.getElementById('card4')
)

Fluxとしてイベントやデータバインディングの実装をしないで、単なるUIの共通化として利用するのもありかと思いました。