3.3K Views
July 24, 23
スライド概要
社内勉強会資料
Reactのミニマム UI = f(data)(state)+sideE ect ff 依田 啓佑
前置き① 👉 1. 学習のインセンティブ 前置き② 👉 2. Reactの特徴 本題 👉 3. ReactによるUI記述のコンセプト
1. 学習のインセンティブ - 技術者面 - 組織面
技術者視点 - ① 現世代のアプリ開発で使用率が高く需要有り ② 次世代技術もパラダイムは受け継いでいる React GUIプログラミング パラダイム 宣言的・リアクティブ・関数コンポーネント / イミュータブル 手続的 / ミュータブル Blazor(C#)、yew(Rust) プログラミング 言語 WebAssembly(なんでも) Javascript/Typescript Fresh、Qwik HTML生成場所 サーバサイド クライアント React パフォーマンス 担保の仕掛け 仮想DOMで解決 エッジ svelte、solid コンパイル時に解決
組織視点 - ① 他社サービスへのUX面での競争力劣後防止 ② 開発生産性や採用面での劣後防止 ✓ 高インタラクティブ ✓ サクサク操作 User Experience ✓ デリバリー速度Up ✓ モダン技術スタックという インセンティブ ✓ 開発人口が多い Developer Experience
2. Reactの特徴 - 一般によく言われる3要素 - 本日フォーカスする範囲
Reactの特徴はこのような3要素で語られる 宣言的UI 宣言的State 仮想DOM - 変化の結果のみ書けば良い - 状態遷移があると、中間的表 現である仮想DOMのみ更新 - UIロジックと状態の分離 - 更新前後の仮想DOMの比較 で差分検知、最小コストで 実DOMを更新 Component-baesd - 画面上のコンポーネントを 単位としてコード分割 - 構造と状態と振る舞いと スタイルをカプセル化
3要素が揃って高インタラクティブ・高パフォーマンス・ 高生産性を実現している 宣言的UI 宣言的State 都度ゼロから宣言したビュー の完成系を構築 仮想DOM 差分更新による宣言的記述と 実行速度の両立 コンポーネント は全てJSの関数 として定義 コンポーネント のメモリ軽量な 写像が仮想DOM コンポーネント 階層関係を宣言 的に記述 変更すべきコンポ ーネントのみを更 新する Component-baesd
本資料では、裏の仕組みは最低限に、単一のコンポーネントを想定した ファーストステップの概念理解を目指す 宣言的UI 宣言的State 仮想DOM 本資料で説明を目指す範囲 Component-baesd
3. ReactによるUI記述のコンセプト - Input → 純粋関数 → UI - 状態をどう持つか - 副作用をどう持つか
UI = f(data)(state)+ sideEffect ※ 数式として正しい表現かはわかないのでイメージで
UI = F(data) in Process out
UI = F(data) Propsは要は引数 Reactコンポーネントに渡すも のをそう言っているだけ Props (引数) コンポーネント 関数 (Javascript関数) DOM (文書構造) JSXを、HTMLと 同じ、DOMの一つ の実装として捉え る。 コード例 引数: greeting 関数: Component1 戻り値: <div className=“One"> 配下のJSX要素
補足: JSXはReact.createElement()の構文糖衣 Props (引数) コンポーネント 関数 (Javascript関数) 仮想 DOMを返す 関数 JSXも実際には ReactElementを 返す関数、である
補足: Reactプロジェクトの初期構造および初回レンダーの ざっくり流れ Index.html <div id=“root”> </div> createRoot(rootElement) Index.js Reactのルート オブジェクト root.render(ReactElement) App.js React Element 種々のコンポーネント ツリーがぶら下がる
UI = f(state) State 純粋関数は、変数を持たない。 一方で、現実に表現しなければならな い状態を管理する必要がある。 ex) フォームに入力された文字、 チェックボックスの選択状態、ログイ ン中のユーザ情報… 純粋関数 JSX
UI = F(state) textState コード例 State hooksAPI群の、useState()とい うAPIが組み込み。 → 状態ストアおよびその更新アク ションとコンポーネントを紐づけ る。 純粋関数 JSX JSX
UI = F(data)(state) ビュー (コンポーネント) 更新後のstateで、 コンポーネント関数が 再実行される イベントリスナー に登録された更新 関数が実行 Store Action (state) (setState) コンポーネント関数と は別領域にストアされ ている状態を更新 stateおよび更新関数は、メモリ上のどっかに保存されてい る。(雑だがそれはReactが知っていれば良い事)
状態遷移に伴い、スナップショットとしてのUIが破棄生成されている。 (常に存在する何か、の内部状態が変化していくというわけではない) f(“初期状態”)の世界線 f(“こんちには”)の世界線 f(“本当はエラーやロー…”)の世界線
UI = F(data)(state) + sideEffect Props 純粋関数 ff 現実には、UI(JSX)をリターンするという主目的以外 に、副目的のための手続的なコードの必要がある。 ex) チャットアプリを想定し、サーバ側とコネクショ ンを張る処理など(コンポーネントの描画と共に、 listenする必要がある。) JSX sideE ect
UI = F(data)(state) + sideEffect Props 純粋関数 ff ff hooksAPI群の、useE ect()というAPIが組み込 み。 → 現実世界になんらかの副作用を及ぼすコードを書 ける。 JSX sideE ect コード例
UI = F(data)(state) + sideEffect State Props (引数) コンポーネント 関数 JSX (文書構造) ff sideE ect 差分検出・差分更 新を経て実際の HTMLに…
補足: ミニマム以上の部分のチラ見せ
エラー、ローディング制御、バックエンドサービスからのデー タ取得
Component - based再び エラー境界 ローディング境界 State useState()は使わないが、サーバ データもコンポーネントが持つ”状態” Prop コンポーネ s ント ff ff useE ect()は使わないが、サーバ データ取得もマウント時に実行 JSX side E ect
仮想DOMおよ びRenerの流れ 再び 初回に、配下の関数を全て実行しrender() その後、ユーザインタラクション等により、ここ のStateかpropsが変化したとする。 → このコンポーネントとその配下のコンポーネン ト関数を再実行する
仮想DOMツリー リアルDOMツリー エ ロ エ ロ エ ロ エ ロ 旧 エ ロ エ ロ エ ロ エ ロ エ ロ React-DOMが 差分検知+日DOM更新 エ ロ エ ロ エ ロ エ ロ エ ロ エ ロ エ ロ 新 エ ロ エ ロ エ ロ Reactが新しい ReactElementを 作成 エ ロ エ ロ
ありがとうございました!