React Bootstrap ってなんて素敵なんだ

普段 Bootstrap を使ってレイアウトや UI コンポーネントを作っていると DOM がえらいことになるので、React で楽してみようという内容です。

## React Bootstrap

[__React Bootstrap__](https://react-bootstrap.github.io/) は Bootstrap のコンポーネントを JSX で扱えるようにした素敵なライブラリです。

たとえば、Bootstrap でまず書くであろう `<nav class="navbar navbar-default">` とかは以下のように JSX で使えます。

```js
var Navbar = ReactBootstrap.Navbar;

var navbarInstance = (
  <Navbar inverse toggleNavKey={0} fixedTop={true}>
    ...
  </Navbar>
);
```

これだけだとウマミがわからないですよね。
ということで JavaScript でループ処理回すだけで構成できちゃいそうなポートフォリオのページ（[こんなの](http://ironsummitmedia.github.io/startbootstrap-3-col-portfolio/)）を React Bootstrap を使って作ってみます。

![image](https://qiita-image-store.s3.amazonaws.com/0/81547/d383411c-c724-e81a-8822-ce03340e33a0.png)

## ポートフォリオ ページを作ってみる

先に完成図をお見せしますとこんな感じ。
よりシンプルにするためにナビゲーションバーなどは省いています。
内容は [Leaflet.js](http://leafletjs.com/) のサンプル集です。
各アイテムはタイトル、サムネイル、デモ/ソースコードを見るためのボタンで構成されています。
至ってシンプル。

![image](https://qiita-image-store.s3.amazonaws.com/0/81547/5bacbad3-c6e9-a8df-4f79-787bbcd8e476.png)

では早速作っていきます。

最終的には一個の `<div>` になるので以下のように BODY タグ内に配置。
リアル DOM はこれだけなので、HTML はとってもスッキリ。

```html
<!-- ここに React コンポーネントをまるまる配置します -->
<div id="containerDOM"></div>
```

React Bootstrap から必要なコンポーネントを呼び出します。

```js
var Grid = ReactBootstrap.Grid;
var Row = ReactBootstrap.Row;
var Col = ReactBootstrap.Col;
var Button = ReactBootstrap.Button;
```

ざっと対応関係はこんな感じでしょうか。

| React Bootstrap | Bootstrap |
|:-----------:|:------------:|
| `<Col xs={12} md={4}>` | `<div class="col-md-4 col-xs-12">` |
| `<Row>` | `<div class="row">` |
| `<Grid>` | `<div class="container">` |
| `<Button>` | `<button type="button" class="btn">` |

呼び出したコンポーネントを使ってループ対象となるアイテム一式をコンポーネント化するためにクラスを作成します。
ソースとなるデータ参照を定義して、JSX で DOM を構成し、ボタンのクリックイベントを定義するだけです。

```js
// アイテム コンポーネント
var Layout = React.createClass({
  // 初期値の設定
  getInitialState() {
    return {
      infos : infos // ここに各サンプルの情報が配列で入ってます
    };
  },
  // [View Demo] ボタンのクリックイベント
  showDemo(e) {
    location.href = e.target.title;
  },
  // [View Code] ボタンのクリックイベント
  showCode(e) {
    location.href = e.target.title;
  },
  render() {
    var showDemo = this.showDemo;
    var showCode = this.showCode;
    // ループ処理でサンプルの情報を DOM に割り当て
    var items = this.state.infos.map(function(info) {
      return (
        <Col xs={12} md={4} key={info.filename}>
          <div className={"item"}>
            <div className={"title-header"}>
              <h3>{info.title}</h3>
              <p>{info.filename}</p>
            </div>
            <div className={"avatar"}><img src={info.imgUrl} alt="" /></div>
            <p>
              <Button className="btn btn-demo" title={info.demoUrl} onClick={showDemo}>View Demo</Button>
              <Button className="btn-github" title={info.codeUrl} onClick={showCode}>View Code</Button>
            </p>
          </div>
        </Col>
      );
    });
    // 上のループ処理で作成した items を配置
    return (
      <Grid>
        <Row>
          {items}
        </Row>
      </Grid>
    )
  }
});
```

クラスができたので `render()` して完了。

```js
ReactDOM.render(<Layout />, document.getElementById("containerDOM"));
```

あとはサムネイルとかボタンとかコンテナを対応する JSX の `className` を使って CSS を書いてリデザインして終わり。

なんと簡単。。

完成品は[__こちら__](http://muxlab.github.io/map-effects-100/)。

今回[紹介した JSX](https://github.com/muxlab/map-effects-100/blob/gh-pages/index.html) とか最後の[おまけの CSS](https://github.com/muxlab/map-effects-100/blob/gh-pages/assets/style.css) などは GitHub リポジトリにあるのでご自由にお使いください。
個人的に JSX 好きなので、コンパイルしないで置いてあります。
ライブデモのソースもプリコンパイルしてないんですが、これくらいだとディレイはあまり感じないですね。