React
参照1:
https://www.youtube.com/watch?v=Otrc2zAlJyM
Reactとは
フロント目指すならReact or Vue or Angular必須
ReactはWebのUIを作る
UIは2つに分類される
見た目(View)
機能(Controller)
2つ合わせたものがコンポーネント ← Reactはこのコンポーネントを作る
React = SPAではない
SPA作るのにReactを使うのは便利だが、Reactで作ったもの全てがSPAなわけではない
差分描画
変更されたVirtual DOMの差分を再描画
Virtual DOM・・・Reactで管理するDOM
ブラウザのレンダリングと別管理 → 効率よくDOM操作できる
参照2:
https://www.youtube.com/watch?v=FuYdTDx8ZP4
JSX
JSX → JavaScript内でHTMLを簡単に記述するための言語 → JavaScriptの拡張言語
なぜJSX?
通常のJSでHTMLを記述(DOM操作)すると量が多くなるとわかりづらくなる
JSXだとHTMLっぽく書けるから可読性が高い
JSXの構文はブラウザは理解できない → ブラウザに理解させるためにJS(EC6)とかにトランスパイルする必要がある(Babel, CoffeeScript , TypeScript ...etc)
JSXの基礎文法
1.Reactパッケージのインストールが必須
2.HTMLとほぼ同じ記述に(classはclassNameに)
3.{}内に変数や関数を埋め込める
4.変数名などは全てキャメルケースで書く
5.空要素は必ず閉じる
code:jsx
//1.
//.jsxファイル内の先頭で宣言する
import React from "react"
//2.
const App = () => {
return(
<div id ="hoge" className ="fuga">
<h1>Hello, World</h1>
</div>
);
};
//3.
//{}で囲まれたものはJSの世界になる
const foo ="<h1>Hello, World</h1>"
const app = () => {
return(
<div id ="hoge" className ="fuga">
{foo}
</div>
);
);
5.
//HTMLだと、
//<img src="aaaa.png">
//でいける
//jsxだと、
<img src ="aaaaaaa.png" />
//↑みたいに />で閉じないといけない
参考3:
https://www.youtube.com/watch?v=P5lDbRxp9sI
環境構築 create-react-app
create-react-appはnpmじゃなくてnpxで使わないとダメ
create-react-appはReactの開発環境をめちゃめちゃ簡単に構築できるツール
babelとかwebpackの設定が不要
create-react-appのフォルダ
src:コンポーネントを作るJSファイル
public:HTMLファイルや設定ファイル
build:本番環境用のファイル
その他の環境構築ツール
Next.js → サーバーサイドでレンダリングする・・・クライアント側の負担を減らす
参考4:
https://www.youtube.com/watch?v=xhVcWoHAyTs&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=4
コンポーネントの基本 ~データの受渡と再利用~
コンポーネント = 見た目 + 機能
なぜコンポーネントを使うのか?
再利用するため
例えば、ボタンの機能を複数作りたいときに、ボタンコンポーネントがあれば複数利用しやすい
分割統治するため
結合度・凝集度の考え方
変更に強くするため
結合度が低いから変更したいところを変更するだけでいい
コンポーネントの種類
Class Component
classによって定義されたコンポーネント
React.Componentを継承
ライフサイクルやstateを持つ
propsにはthisが必要
renderメソッド内でJSXをreturnする
Function Component
関数型で定義されたコンポーネント
アロー関数で記述
stateを持たない
propsを引数に受け取る
JSXをreturnする
最近のReactではClassComponentをできるだけ使わず、なるべくFunctionalComponentで記述していくという流れがある
なるべくComponentにstateを持たせたくない
Componentを使うためにimportとexportする
propsでデータを受け渡す
code:react
//親コンポーネント
const CBlog = () => {
return (
<div>
<Article title={"React"} />
</div>
);
}
//子コンポーネント
const Article = (props) => {
return (
<div>
<h2>{props.title}</h2>
</div>
);
};
jsxの中でJSの変数を呼び出すには{}を使う
親のコンポーネントから引数を渡すことによって子コンポーネントでは、propsという形で一旦受け取って、{props.xxx}で呼び出す
受け渡せるデータ型
{}内に記述
文字列、数値、真偽知、配列、オブジェクト、変数などなんでも渡せる
文字列は{}なしでもOK
同じコンポーネント内で指定してある変数の場合はpropsは不要で{}で変数名をくくればよい
再利用する
コンポーネントの使い回しが最大の利点
参照5:
https://www.youtube.com/watch?v=j4t0aZge0Mc&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=5
コンポーネントの状態 stateの設定と取得と変更
state(状態)とは?
コンポーネント内で管理する変数
ローカルステートと呼ばれる(Reactコンポーネント内だけで使える)
propsとして子コンポーネントに渡せる
なぜstateを使うのか?
render()内では値を変更してはいけない
setState()で値を変更する
stateの変更 = 再レンダーのきっかけ → ページリロードせず表示を切り替えられる
stateの設定方法
Class Componentが前提 ←Functional Componentはstateを持たないから
constructor()内で宣言
オブジェクト型で記述
stateの取得
どうコンポーネント内ならthis.state.key名で取得できる
子コンポーネントで参照したい場合はpropsとして渡す
子コンポーネントに渡す際は、関数型にして渡す
関数型で書かないと、そこで関数が評価されて無限ループになってしまう。関数型にして関数が呼び出された時に発火するというイメージ
stateの変更方法
setState()を使う
関数にラップするのが一般的
setState()内に記述されたstateのみを変更
参照6:
https://www.youtube.com/watch?v=2jRkPz4-hSo&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=6
コンポーネントのライフサイクル 副作用のある処理を書く
ライフサイクルとは?
コンポーネントの「時間の流れ」
生まれて(発火して)、成長(変更)して、死ぬ(破棄される)までの循環
それぞれの段階で必要な処理を記述
3種類のライフサイクル
Mounting
コンポーネントが配置される(生まれる)期間
主要メソッド
constructor()
初期化(stateなど)
コンポーネントの中で使いたい変数などを最初に定義
render()
VDOMを描画(JSXをリターン)
componentDidMount()
render()後に1度だけ呼ばれる。リスナーの設定やAPI通信に使われる
Updating
コンポーネントが変更される(成長する)期間
主要メソッド
render()
VDOMを再描画
componentDidUpdate()
再render()後に呼ばれる。スクロールイベントや条件付きイベント
Unmounting
コンポーネントが破棄される(死ぬ)期間
主要メソッド
componentWillUnmount()
コンポーネントが破棄される直前に呼ばれる。リソースを解放(リスナーの解除やAPI通信の切断)するために使う
なぜライフサイクルを使うのか?
Reactコンポーネント(関数)の外に影響を与える関数を記述するため
DOM変更、API通信、ログ出力、setState()など
副作用 = 適切な場所に配置すべき処理
参照:7
https://www.youtube.com/watch?v=OHMDMixkVHk&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=7
importとexportでモジュールを使いこなそう
モジュール・・・基本的に1ファイル=1モジュール。任意の場所で読み込んで使用できる
モジュール化の魅力
分割統治できる
大規模のアプリケーションでも管理しやすくなる
任意の場所で読み込める
必要なものを必要な時に使えるようになることで読み込み速度を改善できる
再利用できる
何度も同じコードを書かなくていい
Reactでは1つのコンポーネントが1つのモジュールになる
export
モジュールを使うために・・・export
名前付きexport
1モジュールから複数の関数をexport
クラスはexportできない
書き方は以下のように
1.export function 関数名(){ }
2.export const 関数名 = () => { }
名前なしexport(default export)
1ファイル(1モジュール)につき1export
ES6で推奨のexport方法
アロー関数は宣言後にexport
クラスをexportできる
import
モジュール全体のimport
名前なしexport(default export)したモジュールをimportする
モジュール全体のimport
関数ごとのimport
名前付きexportされたモジュールをimportする
{}内にimportしたい関数
別名import
別名(エイリアス)をつけてimportできる
モジュール全体なら * as name
モジュール一部なら A as B
参照:8
https://www.youtube.com/watch?v=Vzvbke_CLAs&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=8
React Hooks 関数コンポーネントでもstateを扱おう
hookとは
クラスの機能(stateやライフサイクル)をFunctional Componentでも使える
なぜフックを使うのか?
シンプルさを保つため → クラスコンポーネントは難しい
thisを多用する
stateを扱うロジックが複雑
複数のライフサイクルメソッドに副作用のある処理がまたがる
↑上記のものを解決するためにフックを使う
useState()を使う
ステートフックと呼ばれる
クラスコンポーネントの、this.stateとthis.setState()を代替
複数のstateを扱う時はstate毎に宣言
useState()の使い方
useState関数をインポート
import React, {useState} from 'react';
宣言する
const [//state変数名, //state変更関数名] = useState(//state初期値);
jsx内で使う
参照:9
https://www.youtube.com/watch?v=WrOzSzt6u3c&list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7&index=9
React Hooks 関数コンポーネントでもライフサイクルを扱う
useEffect()
ライフサイクルメソッドを代替できる
Functional Componentでライフサイクルを使える
コードをまとめられる
機能ベースになっている
useEffect()の仕組み
レンダー毎にuseEffect()ないの処理が走る
代替できるメソッドは以下
componentDidMount()
componentDidUpdate()
componentWillUnmont()
useEffect()メソッドのパターン
1.レンダー毎
基本の形
useEffect()内にCallback関数を書く
Callbackはレンダー毎に呼ばれる
returnするCallback関数はアンマウント時に呼ばれる(クリーンアップ関数)
code:react
useEffect(() => {
console.log('Render')
return () => {
console.log('Unmounting')
}
})
2.マウント時のみ
第二引数の配列内の値を前回レンダーと今回レンダーで比較 →変更があればCallback関数を実行
第二引数に空の配列を渡すと最初の1回(マウント時)のみ実行される
code:react
useEffect(() => {
console.log('Render')
},[])
3.マウントとアンマウント時のみ
1.と2.の複合系
通常のCallbackはマウント時のみ
アンマウント時はreturn内のクリーンアップ関数が実行される
code:react
useEffect(() => {
console.log('Render')
return ()=> {
console.log('Unmounting')
}
}, [])
4.特定のレンダー時
マウント時に実行される
limitの値(第二引数に指定してある変数)が変わった時に実行される
code:react
useEffect(() => {
console.log('Render')
props
コンポーネントの属性
データの属性に対して参照できるもの
{}でくくって渡す
propTypes
プロパティに対する型チェックをしてくれる
code:React
//example
xxx.propTypes = {
name: PropTypes.string;
//isRequiredをつけるとageのプロパティを設定していないものがエラーになる
age: PropTypes.number.isRequired
}
state
Reactの内部の状態
コンポーネントの内部でのみ利用される
変更できる値(ミュータブル) propsはイミュータブル
Redux
Componentの変更が大きくなった時に管理する
action = jsのオブジェクト
このオブジェクトの中でTypeというキーとTypeに対応する値を持つ
actionCreator
Reducer
状態をどう変化させるかを管理するもの
index.jsでアプリケーション内の全てのreducerを管理する
全てのreducerを1つのreducerにまとめている
code:React
~~~
export default combineReducers({foo,hoge,fuga})
store
storeの中にstateとreducerが入っている
storeの中にstateとreducerの組み合わせをいくつも作ることができる
ログイン認証の機能(state管理)のためのもの、ToDoListのタスク管理のstate管理のためのものなど
この1つのかたまりをsliceと呼ぶ←createSliceにより簡単に作れる
アプリケーションに対して必ず1つだけ存在する
state更新の流れ
ユーザーによるアクション → action creatorによりactionを作成 →アクションをstoreに伝達するためにdispatchを使う → dispatchを実行(useDispatch)することでアクションがstoreの中に伝えられる → reducerがdispatchによって渡されたactionと現在のstateを取り出し、actionとstateの2つの引数を基に新いstateを産出する → storeは新しいstateで現在のstateを更新する
ReactComponentからstateを直接参照できる
useSelector
直近の流れ
React → React Hooks
React-redux → Redux Tool Kit
JS → TS