『ReactでTodoアプリを作ってみよう』読書メモ

# 概要

[『速習 React』読書メモ](https://qiita.com/tak_staygreen/items/d70d7f8eb7fdfed1faa5) に続き、2冊目のReact教本を読み進めた際の読書メモです。
上記の本で基礎を押さえていたのでサクサク読めましたが、逆に本書が1冊目だったら少し大変だったかもしれません。
所要時間は約18時間でした。(後半の2割程度はCordovaの話なので、それを除けば15時間程度)
ローカルストレージやMaterial-UIの話もあり、ちょっとしたアプリなら作れるようになった気がします。

# 書籍概要

- 書籍名：ReactでTodoアプリを作ってみよう
- 著者　：kenpapa
- 発刊日：2018/10/21
- 頁数　：358ページ
- 備考　：Kindle版のみ

# 環境構築

## Android Studio・Cordova

- Android Studioをインストール後に環境変数を設定する（[Android Platform Guide - Apache Cordova](https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html)）
    - JAVA_HOME
        - JDKの場所確認：```$ /usr/libexec/java_home```
        - 環境変数への追加：```$ export JAVA_HOME=(上で確認した値)```
            - 永続化させる場合は```~/.bash_profile```なり```/.zshrc```なりに記述する（以降も同様）
        - 追加確認：```$ echo $JAVA_HOME```
    - ANDROID_HOME
        - Android SDKの場所確認：Android Studio起動 → Preferences → 「Android SDK」で検索 → Android SDK Location
        - 環境変数への追加：```$ export ANDROID_HOME=(上で確認した値)```
        - 追加確認：```$ echo $ANDROID_HOME```
    - PATH
        - 環境変数への追加：```$ export PATH=${PATH}:(ANDROID_HOMEの値)/platform-tools:/(ANDROID_HOMEの値)/tools```
        - 追加確認：```$ echo $PATH```

- JDKバージョンの変更（cordova checking java jdk and android sdk versionsエラーが出た場合）
    - [Cordova向けにJDKを再インストール - Qiita](https://qiita.com/yokokouji/items/f68e74b1788984084af4)
    - [MacのBrewで複数バージョンのJavaを利用する + jEnv - Qiita](https://qiita.com/seijikohara/items/56cc4ac83ef9d686fab2)
        - ```$ brew tap homebrew/cask-versions```
        - ```$ brew cask install adoptopenjdk8```

- Gradleのインストール（ビルド時にGradleがないと怒られた場合）
    - ```$ brew install gradle```

# 読書ノート

## React全般

- JSのフレームワークには大きく分けて「クライアント」で動作するものと「サーバ」で動作するものがある
    - ReactやVueやAngular等はクライアントで動作するもの
    - Express等はサーバで動作するもの

- コンポーネントで管理できるメリットは、アプリの規模が大きくなった際にコンポーネントを増やせば対応できること

- JSXでは```class```の代わりに```className```を使う必要がある（```class```はJSの予約語だから）

- Reactにはデータバインディングの仕組みがあり、テンプレートとロジックの連携をフレームワークが自動的に行なってくれる
    - 一方向のデータバインディング：データが変更されるとUIが変更される
    - 双方向のデータバインディング：上に加えて、UIの変更または操作に応じてデータが変更される

- ```export default```：「そのファイルのデフォルトとして後ろに続くものをexportする」という意味
    - [export defaultってなんだろう - Qiita](https://qiita.com/rena_m/items/b9e79dc88e5c5bc5b245)

- ```value ```または```defaultValue```属性と```onEvent```属性の両方を使用することで、双方向データバインディングが可能

## 親子間のデータ受け渡し

- 親コンポーネントから子コンポーネントにデータを渡す場合
    - 親：```<Child xxx={データ} yyy={データ} ...></Child>```
    - 子：```var1 = this.props.xxx, var2 = this.props.yyy, ...```

- 子コンポーネントから親コンポーネントにデータを渡す場合
    - 親：```<Child bbb={親のメソッド}></Child>```
    - 子：```this.props.bbb(データ)```

## ルーティング

- ルーティングでページ遷移を行う方法はテンプレートで行う方法とロジックで行う方法の2通りがある
    - テンプレートで行う方法：```<Link to="path">リンク名</Link>```
    - ロジックで行う方法：```this.props.history.push('path');```

- ルーティングにはHistoryモードとHashモードの2つのモードがある
    - Historyモード：BrowserRouterをインポートして使う
    - Hashモード：HashRouterをインポートして使う（URLに「#」が含まれる）

- Webサーバ上で起動した際のルーティング方法による違い
    - Historyモード：FQDN以外のページでリロードした際に404が返される（その場合は適当な画面に遷移させる等の処理が必要）
    - Hashモード：FQDN以外のページでリロードしても404は返されない（あくまでルートのURLは変わっていないから）

## ローカルストレージ

- ローカルストレージの使用方法
    - データ保存：```localStorage.setItem('key', 'value');```
    - データ取得：```localStorage.getItem('key');```
    - データ保存（複数）：```localStorage.setItem('key', JSON.stringify(複数データ));```
    - データ取得（複数）：```const value = JSON.parse(localStorage.getItem('key'));```

## Material-UI

- Material-UIの```variant```属性の指定
    - ```<Typography variant="title">```という記述があるが、現バージョンでは```variant```に```title```は指定不可
        - 代わりに```h5```辺りを指定すると良い感じになる（[Typography API - Material-UI](https://material-ui.com/api/typography/)）
    - 同様に```<Button variant="fab">```も現バージョンでは指定不可
        - 代わりに```contained```辺りを指定する（[Button API - Material-UI](https://material-ui.com/api/button/)）

- Material-UIの```<ListItem>```のkey設定
    - ```<ListItem key={i}>```という記述があるが、このままだと「リストの子要素には一意のキーを設定すべき」というWarningが出る
        - ```<ListItem>```の親要素の```<div>```に```<div key={i}>```のようにキーを設定するとWarningは消える
            - 配列をmapした結果をreturnする際は、最上位の要素のキーを設定する必要がある？（未確認）
            - [Lists and Keys – React](https://reactjs.org/docs/lists-and-keys.html#keys)

## Cordova

- CordovaでReactアプリを動かす場合はルーティングモードはHashモードにしておく

- ```$ cordova run android```実行時に「No target specified and no devices found, deploying to emulator」から進まない問題の対応
    - Android StudioでAPIバージョンを下げたAVDを作り直したらいけた（理由は気になるが今回はとりあえずスルー）
        - [Mac に Cordova をインストールしてみたら android のエミュレーターが起動しなかったので対処してみた  |  BeeLabo](https://beelabo.com/web/1334)