react-native-windowsでTodoアプリを作ってわかったこと

# はじめに
- React NativeでiOSとUniversal Windows Platform (UWP) アプリを開発しています。
- React NativeでiOS/Androidアプリを開発している方はよく見かけるのですが、ReactNativeでUWPアプリを開発している方があまりいない…？
ということで、備忘録のような位置付けで書き残しておきます。
- あれ、この情報間違ってるよ！等ありましたら、コメントをいただけると幸いです。

# この記事でわかること
- react-native-windowsの雰囲気
    - どちらかというと、既にReact NativeでiOS/Androidアプリを開発している方向け
- 同じコードで実行した時のiOSとUWPアプリの挙動の違い(原因が分かっていないものもアリ)

# こんな感じのTodoアプリ
- [sample-reactnative-app](https://github.com/sentomo/sample-reactnative-app/tree/install-windows-plugin)
- [React & React Native入門者向けハンズオン#3](https://react-native-meetup.connpass.com/event/55247/)に参加させていただき、[ハンズオン資料](https://github.com/YutamaKotaro/slides/blob/master/Native.md)を参考に作成しました。
    - ハンズオン資料と異なるのは、追加したTodoを2回クリックするとリストから消えるという点です。(本当は1回目のクリックで取り消し線を表示させたかったのですが、それについては後ほど触れます)
![todo-install-windows-plugin.gif](https://qiita-image-store.s3.amazonaws.com/0/200334/a07918c5-69e4-9550-a7dc-695664545919.gif)


# 開発環境
- OS
    - Windows10
- 開発ツール
    - Visual Studio Community 2015
        - オプション機能の一覧からユニバーサル Windows アプリ(UWPアプリ)開発ツールが選択されていることを確認する。
    - Visual Studio Code
- Node.js
    - v8.1.2
- React Native
    - react-native @0.45.1
    - react-native-cli @2.0.1
- react-native-windows
    - react-native-windows @0.45.0-rc.1
    - https://github.com/Microsoft/react-native-windows
- rnpm-plugin-windows @0.2.7

# react-native-windowsの起動方法
- Microsoftが公開している[react-native-windowsのgitリポジトリ](https://github.com/Microsoft/react-native-windows)の**System Requirements**と**Getting Started**を見ながらデモプロジェクトを作成することができます。
- 以下のリンクも参考にさせていただきました。
    - [React Native の Universal Windows Platform サポートを試してみた - ひだまりソケットは壊れない](http://vividcode.hatenablog.com/entry/uwp-app/react-native-introduction)
- Visual Studioで `.sln`ファイルを実行する際、上手くいかないことがありましたが、`ソリューションのクリーン`、`ソリューションの配置`、`ソリューションのビルド`をしたら上手くいきました。(謎

# iOSと挙動が異なるところ
index.windows.js、index.ios.jsのコードが全く同じなのに、以下の点においてiOSとUWPアプリの挙動が異なっていました。

- テキストボックス
- UWPアプリだと取り消し線が効かない
- UWPアプリだとFlatListがスクロールできない

### テキストボックス
- テキストボックスは、`<TextInput>`コンポーネントを用いて実装します。
- UWPアプリではテキストボックス内の右端に`×`が表示されていて、クリックすると入力していた文字をクリアすることができます。おそらくUWPアプリ用に最適化されて表示されているのだと思います。
- ちなみに、UWPアプリでは、TextInputのスタイルでborderColor、borderWidth、backgroundColorを指定しなくても、枠線あり、白背景のテキストボックスを表示させることができます。

```js:index.windows.js
export default class sampleappProject extends Component {

  // 略

  render() {
    const {
      list,
      text,
      listkey,
    } = this.state;

    return (
      <View style={styles.container}>
        <Text style={styles.header}>Todo List</Text>
        <Text style={styles.instruction}>
          Todoを入力してください
        </Text>
        <View style={styles.addContainer}>
          <TextInput
            style={styles.textform}  // ここでTextInputのスタイルを呼び出す
            onChangeText={this._onChangeText}
            underlineColorAndroid="transparent"
            value={text}
          />
          <TouchableOpacity
            onPress={this._onPress}
            style={styles.button}
          >
            <Text style={styles.buttonText}>追加</Text>
          </TouchableOpacity>
        </View>
        <FlatList
          style={styles.list}
          data={list}
          renderItem={this.renderListItem}
        />
      </View>
     );
   }
 }

const styles = StyleSheet.create({

  // 略

  textform: {                 // ここでTextInputのスタイルを定義
    flex: 3,
    margin: 10,
    padding: 10,
    height: 40,
    borderColor: 'gray',      // UWPアプリでは指定しなくてもデフォルトがgray
    borderWidth: 2,           // UWPアプリでは指定しなくてもデフォルトが2
    backgroundColor: 'white', // UWPアプリでは指定しなくてもデフォルトがwhite
  },

  // 略

});
```

- iOSでは、TextInputのスタイルでborderColor、borderWidth、backgroundColorを指定しないと、カーソルしか見えない状態になります。
<img width="1029" alt="iOS_TextInput.png" src="https://qiita-image-store.s3.amazonaws.com/0/200334/7a723e8f-8160-5b2b-c81e-3bfce59fef49.png">

### UWPアプリだと取り消し線が効かない
- 取り消し線は、`StyleSheet.create`で、`textDecorationLine`の値に`line-through`を指定すると表示できます。ただし、UWPアプリでは冒頭のgifでお見せした通り、取り消し線が表示されません。。。
    - [line-throughの指定箇所](https://github.com/sentomo/sample-reactnative-app/blob/install-windows-plugin/index.windows.js#L189)
- ReactNativeでは、`textDecorationLine`の値として`none`, `underline`, `line-through`, `underline line-through`は対応しているはず。
![textDecorationLine.PNG](https://qiita-image-store.s3.amazonaws.com/0/200334/5680d114-ceea-56aa-cd54-dc1e96b58d3e.png)
しかし、UWPアプリでは`line-through`を指定しても、`none`のような挙動になります。
- 原因は分からず、、、(原因や代替案などをご存知の方は教えていただきたいです…！)
- iOSだと取り消し線を表示できます。
<img width="1029" alt="iOS_textDecorationLine.png" src="https://qiita-image-store.s3.amazonaws.com/0/200334/083f5b33-63a7-0b09-9f88-473997e800ac.png">

### UWPアプリだとFlatListがスクロールできない
- 追加されたTodoを表示するTodoリストの部分を`<FlatList>`で実装。
- React Nativeの公式ドキュメントを見ると、FlatListはスクロールできるとのことですが、UWPアプリだとスクロールが効いてくれません。
- タッチ操作ができる実機での動作確認ができていないので何とも言えませんが、少なくとも、Visual Studioで、ソリューション構成を`Debug`、ソリューションプラットフォームを`x64`、開始ボタンの横にあるドロップダウンリストから`ローカル コンピューター`を選択して実行した時にはスクロールできません。
- こちらも原因は分からず、、、
- iOSだとスクロールできます。
![iOS_FlatList.gif](https://qiita-image-store.s3.amazonaws.com/0/200334/bdfe1c14-3a4a-839f-4c0d-6f1114bfc66c.gif)

# ざっくり所感
- react-native-windowsを導入すれば大体は同じコードでiOSとUWPアプリを作れるので便利。個人的にSwift, Objective-C, C#ではなく、JavaScriptでiOS/UWPアプリを開発できるのはとても良いです。
- アプリをシミュレーター(UWP)/エミュレーター(iOS)で起動後のデバッグ方法が、同じである点も良いです。
    - iOSは `command` + `D`
    - UWPは `ctrl` + `shift` + `F10`
- ところどころ挙動が異なるので、実行しながら確認が必要。
- 今回のTodoアプリではライブラリを使用していないが、ライブラリによってはUWPアプリに対応していない場合があるので注意。
- react-native-windows関連で調べてもまだ情報が少なく、UWPアプリをReact Nativeで開発している人は少なそうな印象。
    - https://trends.google.co.jp/trends/explore?q=react-native-windows,react-native
- ということで、react-native-windowsの輪を広げたいです！！！