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>
    )
}

コンポーネント作成方法の変遷

  1. createClass関数(廃止)
  2. クラスコンポーネント(将来廃止)
  3. 関数コンポーネント(最新)

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 Contextの使い方 - Qiita

プロジェクトを新規作成するコマンド

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につくプレフィクス。

参考
React hooksを基礎から理解する (useEffect編) - Qiita

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をインスタンスとみなす

Reference

Archives