0から始めるjs未経験者向けReact Native入門

React Nativeをざっくり動かすまで＋簡単なアプリを作るのに必要な知識をまとめてみました。
Xcodeはインストールされている前提で進めます。

※javascriptはほぼ未経験なのでミスの指摘をいただけるとすごい嬉しいです。
※最近の記法にあわせ修正加えました


## インストール
[公式](https://facebook.github.io/react-native/docs/getting-started.html)のコマンドを打ち込みます。

特に問題なく進むと思います。

## プロジェクト作成
ターミナルで、
`react-native init [project name]`
と打つだけでできます。

## ソース,リソース構成

**index.ios.js/index.android.js** がアプリ起動時に実行されるコードです。
あとは任意のフォルダに `.js` ファイルを配置して編集すればOKです。自分はどこかでみたサンプルに従い、 `./App/` 配下においてます。

画像リソースは適当なフォルダにおいて相対パスでアクセスすればOKです。iOSのように@2x,@3xをおけばいいようにしてくれます。

```html
<Image source={require('../images/icon.png')}/>
```

各OS固有のリソース(assets/drawable)にアクセスしたい場合は **image!** をつけます

```html
<Image source={require('image!icon')}/>
```

## OS別処理

`[filename].ios.js,  [filename].android.js` というファイル名にすればOSにあわせて適切に読み込んでくれます。

また、コードの一部を切り替えたい場合は `Platform.OS` で識別可能です。

```jsx
if (Platform.OS === 'ios') {
} else if (Platform.OS === 'android') {
}
```

よっぽど大きく組み替えるのでなければ分岐処理で困らないと思います。

StyleSheetでもできるので [公式ドキュメント](https://facebook.github.io/react-native/docs/platform-specific-code.html) を確認してください。

## 実行&デバッグ


`react-native run-ios` と入力すれば動くはずです。
このとき、後ろでターミナルが開くはずですがこいつは閉じないでください。アプリが動きません。
また初回時のみうまくアプリが起動しないことがあるので、このときは一旦アプリを終了して再起動しましょう。

ここからが重要で、 **React Native はアプリ起動中でもReload可能です**。

２つモードがあります
* エミュ上でCommand+R。 手動Reload
* エミュ上でCommand+DをおしLiveReloadを選択。自動Reload

このおかげで、アプリを再起動せずにコードの修正・確認ができ、非常にスムーズにデバッグできます。

特にLive Reloadは .jsファイルの保存で即反映されるので非常に楽です。

ただ、エラーが出ると動作しないときがある模様...リソースの変更にも弱い印象です。
ダメなときはおとなしくアプリごと再起動してください。

## 試してみる

プロジェクトを作成しアプリを起動すると、適当な文章つきの画面が出るはずです。
せっかくなので、Live Reloadを有効にして色々ためしてみましょう！

1. アプリ起動。エミュでCommand+Dを押し、 *Enable Live Reload* を選択
2. index.ios.jsをお好みのエディタで開く。なんならXcodeでも...
3. `Welcome to...` の部分を `Hello React` と書き換え保存しましょう。エミュに反映されるはず！
4. .jsの下の方に `var styles=...` とあるので探してください
5. `welcome=...` の部分に 
   `color='#F00', backgroundColor='#FF0',` 
   と書き加えて保存しましょう！
6. 文字の色や背景が変わるはず！
7. あとは色々いじってみましょう

念のため、 stylesのwelcome部分を書いておきます

```js
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
    color : '#F00',  //add
    backgroundColor : '#FF0', //add
  },
```

## jsファイルの基本構成

コードにコメントで書く方式で、コードの基本構成・注意点をまとめていきたいと思います。(※実際にこういうコメントを書くとエラーになる場所があるので注意してください)

```jsx
//テンプレ
import React, { Component } from 'react'
//使う標準クラスのインポート。
import {
  StyleSheet, //StyleSheet。ほぼ必須。
  View,  //レイアウトに使うのでほぼ必須
  Text,  //TextViewじゃない。注意
  //もろもろ必要なものを書く
} from 'react-native';

//自作クラスのインポート。パスに注意!
import OtherView from './App/OtherView' 

//ようやくクラス作成
//外部から使う場合はexport (default)
export default class MyView extends Component {
   //renderが必須メソッド。viewを返す
   render() {
      return (  //ViewのXMLを () で囲む
         <View style={styles.test}> { /* styleは {}で囲む */ }
           <Text style={styles.text}>
             TEST  { /* 文字列はTextタグで囲む */ }
           </Text>
         </View>
      );
   }
});

//Styleの作成
const styles = StyleSheet.create({ //こっちも ({
  test : {
    いろいろかく
  },  //カンマ!
  text : {省略},
});

```

実際にやってみるとしょっちゅうエラーの赤い画面がでると思います...ある程度やるとどの辺に原因があるかわかるのですが、最初はよくわからなかった...

よくあったのが、 **カンマの漏れ** です。もちろんスペルミスも...注意深く観察してください。

## 状態管理

Reactではクラスフィールドで状態を管理するのではなく、 **state** で管理します。

stateは以下のようにして扱います。

* constructor() で初期値を設定
* this.state.xxx で取得
* this.setState() で更新

this.state.xxx = XXX ではないで注意してください。


```jsx
exports class MyView extends Component {
   //初期値を 名前 : 値のセットで返す
   constructor() {
      super();
      this.state = {
        text : 'TEXT'
      }
   }
   render() {
      //render内などで、this.state.xxxで値取得
      return (
          <Text>  {this.state.text}  </Text>
      );
   }
   //onclick部分は書いてませんが、クリック時に呼び出されると思ってください
   onClick() {
     this.setState({  //{}で囲むよう注意
        text : "CLICKED",
     });
   }
}
```

特に難しくないと思います。


## レイアウトの基本

ぶっちゃけ、 **Androidとよく似てます**。
LinearLayoutとFrameLayoutで組む感じです。

似たように機能するStyleの対応表が以下です(完全一致じゃないです)

| Android | React(StyleSheet) |
|:--:|:--:|
|LinearLayout(Vertical)| Viewで、flexDirection : 'column' |
|LinearLayout(Horizontal)| Viewで、flexDirection : 'row' |
|FrameLayout| Viewの子Viewで、 positoin: 'absolute', left/top/right/bottom:[数値]|
|-----|--------|
| gravity | alignItems(水平), justifyContent(垂直)|
| layout_gravity | alignSelf (水平のみ) |
| wrap_content | flex : 0(デフォルト) |
| match_parent | flex : (>0) |
| layout_weight| flex : [数値] |
|-----|--------|


基本的にこれらを組み合わせれば、Android相当のレイアウトはほぼできると思います。

`flex:` がちょっと特殊でしょうか。 (>0)で親を埋めるように動作し、何個か(>0)ある場合はそれぞれの数値にあわせてサイズが決まります。（たぶん...）

## 最後に

自分自身、恥ずかしながらjavascript経験が浅すぎてまだ手探りです。
仕事レベルでは厳しいですが、趣味ならReact Nativeでいいかなと。

最後に個人的に感じているReact Nativeのメリットを。

* AndroidのようなXMLレイアウト(Auto-Layoutより簡単, 特に修正が楽)
* Stylesでの共通スタイルの定義(iOSにはこの概念がない、Androidは定義が面倒)
* Live Reload

徐々に広がってきた印象ですね。Nativeメインの人よりWebメインの人のほうが楽に作れるとは思います。