Reactの基礎勉強記録

#はじめに
初学者の私がReactについて学んだことをアウトプットする記事です。
主な目的は自分がこの記事を開けばReactについて復習できるようにする備忘録です。

#目次
* Reactとは
* JSXの基礎知識と文法
* create-react-app
* コンポーネントの基本データの受け渡しと再利用
* コンポーネントの状態stateの設定と取得と変更
* コンポーネントのライフサイクル 副作用の有る処理を書こう
* importとexport モジュールを使いこなそう
* React-Hooks 関数コンポーネントでもステートを使おう
* React-Hooks 関数コンポーネントでもライフサイクルを使おう

# Reactとは
##概要
Facebook社が開発したライブラリで、WebのUIを作るもので、決してSPAを作るものではない。
チャットボットだけReact、ボタン機能だけReactで実装することも出来る。

##コンポーネントとは
UIは2つに分類される。
1. 見た目（View）
2. 機能（Controller）
コンポーネント＝見た目＋機能

##コンポーネントのツリー構造
HTMLの下にヘッダーやメイン、その下にnav,login-button,content,linkなどが存在する。

##DOM
DOM＝Document Object Model＝インターフェイス
HTMLにアクセスする窓口
HTML構造、見た目、コンテンツを変更する

##Virtual DOMとは
ブラウザのレンダリングと別管理、効率よくDOM操作できる。
###通常のDOM操作の場合、
`document.getElementById('hoge').innerText = 'fuga'`
###ReactのVirtualDOM操作
`render(<div id='hoge'>fuga</div>)`

##差分描画について
変更されたVirtualDOMの差分を再描画するので、従来のHTMLをまるごと受け渡しするより早く描画できる。

##JSXが使える
JavaScript内でHTMLっぽく書ける。
Reactの最大の強み。

# JSXの基礎知識と文法
##JSXとは
JavaScript内でHTMLを簡単に記述するための言語で、JavaScriptの拡張言語である。
Facebook社が開発していて、Reactの公式ドキュメントはほぼJSXで書かれている。
Reactでは業界標準である。

##なぜJSXなのか （わかりにくいので後で書き直します）
通常のJavaScriptでHTMLを記述すると(DOM操作)

```
const fuga = '<h1>Hello,World!</h1>'
document.getElementById('hoge').innerHTML = huga
```
となる。
量が増えると、`const foo='<h2>React Commentary</h2>`したあと、それのID、中身を変数で代入しなければならない。それをそれぞれやらなければならないので、わけわからなくなる。
JSXを使えばHTMLっぽく書けて可読性が高い。それだけでJSXを使う理由がある。

##トランスパイラとは
翻訳のような役割。
JSXの構文はブラウザが理解出来ないので、トランスパイラで翻訳する必要がある。
例えば、JSXからJavaScript（ES６）など。
トランスパイラはBabel,CoffeeScript,TypeScriptなどが使われる。
##もしJSXが無かったら
React.createElementを使う羽目になり、いちいちこれでHTMLを宣言しなければいけなくて面倒。
トランスパイラで翻訳されたあとはこのcreateElementが使われている。
##基礎文法
###Reactパッケージのインストールが必須。
.jsxファイルの先頭で宣言する。
`import React from 'react'`
###HTMLとほぼ同じ記述
例外はある。
`<div class='hoge'> → <div className='hoge'>`
など。
###{}内に変数や関数を埋め込める

```
const foo = <h1>Hello</h1>
{foo}
```
で`Hello`が表示できる。
つまり、{}内だけはJavaScriptの空間に出来る。

###変数名などは全てキャメルケースで書く
javascriptなので、fooBar,classNameなど、ラクダのコブのように単語の区切りが大文字になる。
ハイフンで繋ぐケバブケースは使わない。foo-bar,class-nameなどは禁止。

###空要素は必ず閉じる。
HTMLでは`<input ~~~ >`でよいが、Reactでは`<input ~~~ />` `<img ~~~ />`のように、`/>`で閉じる必要がある。

# create-react-app
##簡単に言うと
React開発環境をワン・コマンドで。
##必要なもの
* node 8.10
* npm 5.6
* インストール用にhomebrewとnodebrew

##なぜこれを使うのか
普通に環境構築しようとすると、くっっっっっっっっそ難しい。
トランスパイラのbabelやバンドラのwebpackの設定が必要だからである。
熟練者でもこれは難しいらしい。

##create-react-appで作成されるフォルダ
* src:コンポーネントを作るjsファイルを入れる
* public:htmlファイルや設定ファイルを入れる
* build:本番環境用のファイルを入れる

###src(ソースフォルダ)の中身
js,cssをrootに書き換えて、publicのindex.htmlで出力する。
###publicフォルダの中身
* favicon.ico:タブの左側のアイコン
* 画像ファイル
* manifest.json:ホーム画面に追加が出来る設定ファイル

###buildフォルダの中身
srcの中に入ってたものを１つにまとめて入れてある。
まとめる役割を持つのがバンドラ（webpack）。

##コマンド集
###npm run build
srcとpublic内のファイルを１つにまとめて（バンドル）、buildディレクトリに出力する。
同時にトランスパイル（翻訳）もされている。
###npm start
ローカルサーバーを起動してReactアプリを確認できる。
###npm run eject
babelやwebpackの設定を変更する

##その他の環境構築ツール
* Next.js : SSR,SSGが出来る。SEO対策に最適。これからどんどん流行るであろう今最もアツいフレームワーク。
* Gatsby : 静的ウェブサイトに使える。

# コンポーネントの基本 データの受け渡しと再利用
##最初に
コンポーネントとは見た目プラス機能ということ
##なぜコンポーネントを使うのか
###再利用するため
ボタンコンポーネントに引数を渡して(props)色んな場所で使う
###分割統治するため
それぞれのコンポーネント同士は互いに関連しあわないことで管理しやすい（疎結合）
###変更に強くするため
分割統治すると変更に強くなる。
コンポーネントを変更しても、他のコンポーネントには一切関係がない（アトミックデザイン）

##コンポーネントの種類
* Class Component : クラスによって定義されたコンポーネント（React-Hooksがデファクトスタンダードになっている現在、ほぼ使われていないので注意）
* Functional Component : 関数型で定義されたコンポーネント

##FunctionalComponentの特徴
* ES6のアロー関数で記述
* stateを持たない(stateless)
* propsを引数に受け取る
* JSXをreturnする。

##ClassComponentの特徴
* React.Componentを継承
* ライフサイクルやstateを持つ  
コンポーネントが出てくるときにどう動くか、消えるときにどう動くか、これをライフサイクルと言う。
* propsにはthisが必要  
this.propsの意味は、このクラス内のporpsだよって意味
* renderメソッド内でJSXをreturnする
* 記述量が多い代わりに状態（state）を持てる  
（最近はクラスコンポーネントを使わず、なるべくファンクショナルコンポーネントを使う。）

##propsでデータを受け渡す
親コンポーネント

```
const Blog = () => {
  return (
    <div>
      <Article title={'React'} />
    </div>
   );
}
```
子コンポーネント

```
const Article = (props) => {
  return (
    <div>
      <h2>{props.title}</h2>
    </div>
  );
}
```

##受け渡せるデータ型
{}内に記述する。
文字列、数値、真偽値、配列、オブジェクト、変数、何でも渡せる。
文字列は{}無しでもOK

##再利用する
コンポーネントを使い回す。

```
<Articl title={'React'} />
<Articl title={'JSX'} />
```

# コンポーネントの状態 stateの設定と取得と変更
##状態（state）とは
* コンポーネント内で管理する変数
* ローカルステートと呼ばれる。（reduxではグローバルステートがある。）
* propsとして子コンポーネントに渡せる。

##なぜstateを使うのか
* render()内で値を変更してはいけないから。
（stateが変わると再レンダーされる。その際にまたstateが変わって再レンダーされる。以下無限ループ）
* setState()で値を変更する。
* stateの変更＝再レンダーのきっかけ
ページリロードせず表示を切り替えられる。

##stateの設定方法
* ClassComponentが前提
* constructor()内で宣言
* オブジェクト型で記述

```
constructor(props) {
	super(props);
	this.state = {
		isPublished: false }}
```
##stateの取得
* 同コンポーネント内ならthis.state.key名で取得できる
* 子コンポーネントで参照したい場合はpropsで渡す
* `<Article title='React' isPublished={this.state.isPublished} /> `で渡せる

##stateの変更方法
* setState()を使う
* 関数にラップするのが一般的
* setState()内に記述されたstateのみを変更
* 公開状態を反転させる関数を定義する

```
togglePublished = () => {
	this.setState({
		isPublished: !this.state.isPublished }) };
// ここの！は反転させるの意味
```

# コンポーネントのライフサイクル 副作用のある処理を書こう
##ライフサイクルとは
* コンポーネントの時間の流れ
* 生まれて、成長して、死ぬまでの循環
* それぞれの段階で必要な処理を記述
* Reactの基礎中の基礎

##３種類のライフサイクル
* Mounting ： コンポーネントが配置される（生まれる）期間
* Updating ： コンポーネントが変更される（成長する）期間
* Unmounting ： コンポーネントが破棄される（死ぬ）期間

##なぜライフサイクルを使うのか
* 関数の外に影響を与える関数を記述するため
DOM変更、API通信、ログ出力、setState()など
* 副作用＝適切な場所に配置すべき処理

##それぞれの期間
* Mounting→constructor()→render()→componentDidMount()
* Updating→render()→componentDidUpdate()
* Unmounting→componentWillUnmount()

##主要メソッド（Mount）
* constructor() : 初期化（stateなど）
* render() : VDOMを描画（JSXをリターン）
* componentDidMount() ： render()後に１度だけ呼ばれる。リスナーの設定やAPI通信に使われる

##主要メソッド(Update)
* render() : VDOMを再描画
* componentDidUpdate() : 再render()後に呼ばれるスクロールイベントや条件付きイベント
例（新しいコメントが入ってきたときに、そこにスクロールするなど。）

##主要メソッド(Unmount)
* componentWillUnmount() ： コンポーネントが破棄される直前にリソースを開放するため
リスナーの解除など。API通信の解除など。

#importとexport モジュールを使いこなす
##モジュール化とは
* 多言語では昔からある概念
* JavaScriptではES6から
* 基本的に1ファイル１モジュール
* 任意の場所で読み込める

##モジュール化の威力
* 分割統治できる ： 大規模プログラムでも管理しやすい
* 任意の場所で読み込める ： 必要なものを必要な分だけ
* 再利用ができる ： 何度も同じコードを書かなくてよい
* Reactはモジュール化を強く推奨してる

##名前付きexport
* １モジュールから複数の関数をexport
* クラスはexportできない
* `export funcrion 関数名（）｛｝`
* `export const 関数名 = () => {}`

##名前無し(default)export
* １ファイル（１モジュール）１export
* ES6で推奨方法
* アロー関数は宣言後にexport
* クラスをexportできる

##モジュール全体のimport
* 名前無し(default)exportしたモジュールをimportする
* モジュール全体のimport

##関数ごとのimport
* 名前付きexportされたモジュールをimportする
* {}内にimportしたい関数名

##別名import
* 別名（エイリアス）をつけてimportできる
* モジュール全体なら`* as name`
* モジュール一部なら`{A as B}`

#ReactHooks 関数コンポーネントでもステートを使おう
##フックとは
* クラスの機能を関数コンポーネントでも使える
* React16.8から導入
* 100%後方互換だから小さく導入できる

##なぜフックを使うのか
* シンプルさを保つため
* クラスコンポーネントは難しい
* thisという悪魔 ： JavaScriptでは他の言語のthisとは違う挙動をする
* stateを扱うロジックが複雑
* 複数のライフサイクルメソッドに副作用のある処理がまたがる ： componentDidMountでイベントリスナーを設定して、componentDidUnmountで解除する。この記述をまとめたい。
* これらを解決するのがフック

##useState()を使おう
* ステートフックと呼ばれる
* クラスコンポーネントでいう`this.state`と`this.setState()`を代替する
* 複数のstateを扱うときはstateごとに宣言

##useState()の使い方
１． useState関数をインポート ： `import React,{useState} from 'react;`
2. 宣言する ： `const [isPublished, togglePublished] = useState(false);`
左から順に「state変数名」、「state変更関数名」、「state初期値」
３． JSX内で使う ： `<input ~~~ onClick={() => togglePublishec(!isPublished)} />`

# ReactHooks 関数コンポーネントでもライフサイクルを使う
##useEffect()のメリット
* ライフサイクルメソッドを代替出来る
* 関数コンポーネントでライフサイクルを使える
* コードをまとめられる
* 機能ベースがよい（何をやっているのかわかる）
* 時の流れベースはよくない（ライフサイクルのメソッドごとがわかりづらい）

##useEffect()の仕組み
* レンダー毎にuseEffect()内の処理が走る
* 代替出来るメソッドは以下
* componentDidMount
* componentDidUpdate
* componentDidUnmount

##パターン１ レンダーごと
* 基本の形
* useEffect()内にCallback関数を書く
* Callbackはレンダー毎に呼ばれる
* returnするCallback関数はアンマウント時に呼ばれる（クリーンアップ関数）

```
useEffect(() => {
	console.log('Render!')
	return () => {
		console.log('Unmounting!')}})
```

##パターン２ マウント時のみ
* 第２引数の配列内の値を前回レンダーと今回レンダーで比較 ： 変更があればCallback関数を実行
* 第２引数に空の配列を渡すと最初の１回のみ実行される

```
useEffect(() => {
	console.log('Render!')}, [] )
```

##パターン３ マウントとアンマウントのみ
* １と２の複合系
* 通常のCallbackはマウント時のみ
* アンマウント時はreturn内のクリーンアップ関数が実行

```
useEffect(() => {
	console.log('Render!')
	return () => {
		console.log('Unmounting!)} }, [] )
```

##パターン４ 特定のレンダー時
* マウント時に実行される
* limitの値が変わったときに実行される
* 例えば、limitの値がtrueからfalseになったとき。

```
const [limit, release] = useState(true);
useEffect(() => {
	console.log('Render!') }, [limit])
```