React
概要
Reactは、Web開発に使われるJavaScriptライブラリ。変更があった画面の一部だけを更新することで、リロードが必要のない、高速でリッチなWebサイトを構築できる。関数型プログラミングの考え方を背景に持つ。
Memo
引数を受け取るコンポーネントの例
- 複数の引数の受け取り方
- 関数型の型指定の方法
あたりが詰まりポイント。
export const Square = ({ isLive, click, }: { isLive: boolean; click: () => void; }) => { return ( <> {isLive ? ( <button className="square live" onClick={click}></button> ) : ( <button className="square death" onClick={click}></button> )} </> ); };
setStateのインクリメント
引数で前の状態を取り出せる。これで取らないと値が、おかしくなることがある。
const increment = () => setWidth((prevWidth) => prevWidth + 1);
onClickは関数型をとる
プロパティonClickが取るのは関数型である。特に深く考えることなかったので詰まった。
<button className="square death" onClick={() => console.log("テスト")}></button>
<button className="square death" onClick={console.log("テスト")}></button>
hooksの作り方
hookの指針。汎用化できるようにする。 REST APIと良い感じに通信するHookを自作する
サーバーサイドレンダリング
読み込み時はコンポーネントをHTMLで静的に描画。あとからコンポーネントDOMに対してイベントをフックすることで操作できるようにする(ハイドレーション)。 これによって、高速表示ができる。 サーバーサイド(Node)と、クライアントサイド(ブラウザ環境)のAPIは一部異なる部分があるので、これを共通化する必要がある。
通常の、ブラウザでDOMを描画するほうはクライアントサイドレンダリング。
便利ツール
さまざまなReactのためのlintが存在する。
- hook
- eslint-plugin-jsx-a11y
ESLint はコードの正しさを保つのに対し、Prettier はコードの読みやすさを保つためのツール。 同時に使うことができる。
eslint-config-prettier は、ESLint のルールのうち、Prettier と相容れないものを無効化 する共有設定です。一方の eslint-plugin-prettier は、Prettier のルールを ESLint のルー ルに統合するためのプラグインです。つまるところ、これらのパッケージにより、ESLint から Prettier を実行することが可能になります。
prettier でコード形式を統一できる。
TypeScriptのテンプレートで作成。
npx create-react-app my-type --template typescript
fiber
Reactの非同期でDOMの変更を検知する仕組みのこと。
ステート
プロパティはいわばRead-Onlyなデータで、一度コンポーネントが描画されると変更されない。 一方、コンポーネントの描画後に変更されるデータをステートという。
あるコンポーネントのステートの変更が、他のコンポーネントのプロパティに伝播し、それが全体に波及していく…。
Webpack
ReactだけではWEB機能を提供できない。
ほかの機能もまとめてモジュール間を調整するのが、モジュールバンドラ。
Webpack
, Browserify
, Gulp
, Grunt
などが存在する。
一番使われているのがWebpack。
import
をたどって依存モジュールのグラフを作成する。
npm install --save-dev webpack webpack-cli npm install babel-loader @babel/core --save-dev npm install @babel/preset-env @babel/preset-react --save-dev
- webpack.config.js
- .babelrc
を設定する。
単一のファイルにビルドするとエラーが起きたときの行番号がわからなくなる。
ソースマップ
を使うとどこで起きたかわかる。.mapと拡張子のついたファイル。
webpackに設定を追加すると、ビルド時生成されるようになる。
create-react-app
を使うとこれらの作業を自動でやってくれる。
フラグメント
コンポーネントを並列に描画はできない。 1つである必要があるが、いちいち包含コンポーネントを書くのは面倒。 フラグメントを使うと簡潔に1つのコンポーネントにまとめられる。
function Cat({ name }) { return ( <React.Fragment> <h1>The cat's name is {name}</h1> <p><He's good.</p> <React.Fragment> ) } // 省略記法 function Cat({ name }) { return ( <> <h1>The cat's name is {name}</h1> <p><He's good.</p> <> ) }
デストラクチャリングで簡潔に表示する
// ↓使わない例 function Menu(props) { return ( <h1>{props.title}</h1> ) } // ↓デストラクチャリングを使うと簡潔に書ける function Menu({title, recipes}) { return ( <h1>{title}</h1> ) }
コンポーネント作成方法の変遷
- createClass関数(廃止)
- クラスコンポーネント(将来廃止)
- 関数コンポーネント(最新)
package.jsonの例
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start:server": "ts-node -O '{\"module\": \"commonjs\"}' ./server/index.ts", "dev": "concurrently --kill-others \"npm run start:server\" \"npm run start\"" },
Provider
props渡し地獄を回避するための組み込みの関数。
<ExampleContext.Provider value={resource.name}> <NavigationComponent /> // ← このコンポーネントではcontextで値を取得できるようになる。 </ExampleContext.Provider>
プロジェクトを新規作成するコマンド
React+TypeScript、chapter03というディレクトリ名で作成する場合。
npx create-react-app chapter03 --template typescript npm install -D tslint # tslint導入 npx tslint --init # tslint設定ファイル
Context
contextはコンポーネント間で情報をやりとりしやすくするための関数。 コンポーネント間でグローバルに値を共有できる。 が、好き放題に値を変えられると安全性や可読性が下がるので、アクションを通してしか値を変化させられないようになっている。
Reducer
状態とアクションを元に、行うことを振り分ける関数。
Hook
hookはコンポーネントとは独立した関数で、コンポーネントに対して着脱可能な機能を取り付けるイメージ。ステートを追加したいなら useState
。
use
はReact hooksにつくプレフィクス。
hookという名の通り、実行タイミングに関係している。
たとえば、 useEffect
に渡された関数はレンダーの結果が画面に反映された後で動作する。
{} はオブジェクト
jsではオブジェクトを表す表記。
const { state, dispatch } = useAppState()
は、通常のオブジェクトを作る{}と同じ。 つまり、↓と同じ。
{ state, dispatch }
これらに関数の返り値が代入される、とそれだけのこと。
Tasks
TODO React - Speaker Deck
Reactの解説。
- jQueryではDOMをグローバル変数としていじらないといけなかった
- viewがテンプレートとjsで分離していて辛かった
- Reactは宣言的UI。「何」を記述する
- jQueryは命令的UIになりがち。「どうするか」を記述する
- Reactは状態が変わるごとにコンポーネントを毎回実行してDOMを新規に構築
- 毎回新規にレンダリングするのと同等なので、画面の更新について考えることが減る
- 仮想DOM…DOMの代わりにjsのオブジェクト(軽量)で仮想的なDOMを構築する
- 仮想DOMを比較して、差分だけをDOMに反映する
- ReactはUI構築のためのライブラリ。フレームワークではない。Viewに特化している
- JSX … js XML
- jsの式としてXML風の構文を記述できる
- BabelやTS等のツールによってjsの式に変換される
- JSXとHTMLの違い
- 小文字と大文字を区別する
- キャメルケースを使う
- HTMLと異なる属性名がある
- コンポーネント
- コンポーネントは状態を持てる
- 関数コンポーネントは単なる関数で、関数自体は状態を持っていない
- 状態はReactが管理する仮想DOM(Fiber構造体)によって管理される
- 関数コンポーネントからReactが管理する情報とやりとりするためにHooksを使う
- useRef
- OOPにおけるインスタンス変数の代わりに使用すう
- 仮想DOMをインスタンスとみなす
TODO TypeScriptでReactをやるときは、小さいアプリでもReduxを最初から使ってもいいかもねというお話 | フューチャー技術ブログ
Redux Toolkitがなぜ使いやすいかの解説。