OnsenUI and Reactを使ってみる


勉強会で使う機会あったんでメモ。

## Monaca-CLIをインストール
React版のOnsen UIはMonacaのCLIからじゃないと使えないらしいので、npmでインストールします。
https://docs.monaca.io/ja/manual/development/monaca_cli/

```
$ npm install -g monaca

```

monacaコマンドがhelpっぽい動作します。

---

```
$ monaca
 __  __                             
|  \/  | ___  _ __   __ _  ___ __ _ 
| |\/| |/ _ \| '_ \ / _` |/ __/ _` |
| |  | | (_) | | | | (_| | (_| (_| |
|_|  |_|\___/|_| |_|\__,_|\___\__,_|

 Command Line Interface for Monaca and Onsen UI
 Monaca CLI Version 2.0.5

Usage: monaca command [args]

  To learn about a specific command type:

  $ monaca <command> --help

Commands: (use --all to show all)

  create  ........  create a new Monaca project
  preview  .......  runs a local web server for preview
  debug  .........  run app on device using Monaca Debugger
  remote build  ..  build project on Monaca Cloud
  signup  ........  register a new Monaca account
  login  .........  sign in to Monaca Cloud
  clone  .........  clone from Monaca cloud project
  download  ......  download project from Monaca Cloud
  upload  ........  upload project to Monaca Cloud
  plugin  ........  manage Cordova Plugin
  proxy  .........  configure proxy to use when connecting to Monaca Cloud

Typical Usage:

  $ monaca create myproject # Create a new project from various templates
  $ cd myproject
  $ monaca preview # Preview app on a browser
  $ monaca debug # Run the app in Monaca Debugger
  $ monaca remote build # Execute remote build for packaging
```

---

## プロジェクトを作成

```
$  monaca create react-sample
? Choose a category: 
  Onsen UI 
  Onsen UI and Angular 1 
  Onsen UI and Angular 2 
❯ Onsen UI and React 
  Ionic 
  No Framework 
  Sample Apps
```
---

「Onsen UI and React」を選択すると、テンプレートを何にするか聞かれます。面倒なら一番上のでいいでしょう。

```
? Select a template - Press P to see a preview (Use arrow keys: ↑ ↓ ← →)
❯ Onsen UI V2 React Tabbar 
  Onsen UI V2 React Splitter 
  Onsen UI V2 React Navigation 
  Onsen UI V2 React Minimum 
```

Enterを押すと、npm installが始まります。
内部的にはpackage.jsonをDLしてきて、npm installを実行している感じでしょうかね。

---
少し待って以下のメッセージが出たら完了です。

```
Project created successfully.

Type "cd react-sample" and run monaca command again.
  > monaca preview      => Run app in the browser
  > monaca debug        => Run app in the device using Monaca Debugger
  > monaca remote build => Start remote build for iOS/Android/Windows
  > monaca upload       => Upload this project to Monaca Cloud IDE
```
---
##Previewしてみる
せっかくなんでデフォルトの状態で見てみましょう。

```
$ monaca preview
```
---
nodeがhttp-serverを走らせて、localhostにプレビュー画面を出します。
![スクリーンショット 2016-08-01 19.37.39.png](https://qiita-image-store.s3.amazonaws.com/0/23936/7c861e8a-e130-1c31-19cf-18d278120bab.png "スクリーンショット 2016-08-01 19.37.39.png")

こんな感じです。

---
## ディレクトリ構造


```
$ tree -I node_modules -L 3
.
├── config.xml
├── package.json
├── platforms
│   ├── android
│   │   ├── AndroidManifest.xml
│   │   ├── res
│   │   └── splash_default.png
│   ├── chrome
│   │   ├── background.js
│   │   ├── icon.png
│   │   └── manifest.json
│   ├── ios
│   │   ├── MonacaApp
│   │   └── MonacaApp-Info.plist
│   └── winrt
│       ├── app_logo_winrt.png
│       ├── app_small_logo_winrt.png
│       ├── app_splash_screen_winrt.png
│       ├── app_tile_wide_logo_winrt.png
│       └── package_logo_winrt.png
├── src
│   └── main.js
└── www
    ├── css
    │   ├── font_awesome
    │   ├── ionicons
    │   ├── material-design-iconic-font
    │   ├── onsen-css-components-blue-basic-theme.css
    │   ├── onsen-css-components-blue-theme.css
    │   ├── onsen-css-components-dark-theme.css
    │   ├── onsen-css-components-default.css
    │   ├── onsen-css-components-purple-theme.css
    │   ├── onsen-css-components-sunshine-theme.css
    │   ├── onsen-css-components.css
    │   └── onsenui.css
    ├── dist.js
    └── index.html
```

---

Reactのコードは、src/main.jsに書かれています。

---

##コードを見てみる

```src/main.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Page, Tabbar, Tab, Toolbar} from 'react-onsenui';

// load Onsen UI library
import 'onsenui';

class HomePage extends React.Component {
  render() {
    return (
      <Page
        renderToolbar={() =>
          <Toolbar>
            <div className='center'>Title</div>
          </Toolbar>
        }
      >
        <div>
          Home Page
        </div>
      </Page>
    );
  }
}

class SettingsPage extends React.Component {
  render() {
    return (
      <Page
        renderToolbar={() =>
          <Toolbar>
            <div className='center'>Title</div>
          </Toolbar>
        }
      >
        <div>
          Settings Page
        </div>
      </Page>
    );
  }
}

class App extends React.Component {
  renderTabs() {
    return [
      {
        content: <HomePage />,
        tab: <Tab label='Home' icon='md-home' />
      },
      {
        content: <SettingsPage />,
        tab: <Tab label='Settings' icon='md-settings' />
      }
    ]
  }

  render() {
    return (
      <Tabbar
        initialIndex={0}
        renderTabs={this.renderTabs.bind(this)}
      />
        );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

```
この辺はReactとかReact Nativeでよく見かける書き方ですね。