🧫

::: Software Design vol.129まとめ :::

2022/09/26に公開

Reactの特徴

Reactの特徴は大きく2つ

  • コンポーネントという単位でUIを組み立てる手法を採用している
  • 宣言的なAPIによりUIを構築できる
    これらの特徴を提供しつつ、UX(高い反応速度やスムーズな画面遷移)をとても重視している

宣言的UIのメリット

  • アプリケーションの大規模化に対応しやすい
  • UIの実装に秩序と設計をもたらす
    宣言的UIのデメリット
  • ライブラリ利用自体のオーバーヘッドが相対的に大きい
  • DOMの知識以外にライブラリ特有の知識が必要になる

命令的UIのつらさについて

特につらいのはユーザーの操作に反応する場合

  • ユーザーの操作に対する反応速度を最速にしたければ、現在の状態に応じて、そしてユーザーがどのような操作を行ったかに応じて異なる命令を実行する必要がある
  • -> 実装量が増え、メンテナンスも困難になる

宣言的UIライブラリの目的

  • 命令的UIのつらさへの対策として、ユーザーの操作に関わらず、一度画面を全部消して再構築する
  • 出発点がどうなのかということを考慮せずに済むため、実装量が減る
  • UIはライブラリに任せて、状態管理に徹することができる
  • ただ、毎回全ての画面を再構築しているとユーザーの操作に対する反応速度が悪くなるため、Reactでは仮想DOMを用いて画面の差分更新を行っている

クラスコンポーネントと関数コンポーネント

昔の関数コンポーネントは機能が少なかった。
propsを受け取って描画結果を生成する以外のことができず、コンポーネント内にステートを保持したり、componentDidMountのような副作用を備えることができなかった。
しかし、React16.8でhooksが追加されたことにより、クラスコンポーネントを使わないとできなかったことが、関数コンポーネントでもできるようになった。

hooks

hooksが導入されたことにより、より簡潔に書けるようになり、より優れた設計でコンポーネントを実装することができるようになった。

純粋性

純粋性とは、関数が副作用を起こさないこと。
ここでの副作用とは、与えられた入力から出力を計算する以外の動作のことで、入出力以外の手段でコンポーネントの外部に影響を与えたり、外部から影響を受けたりするような処理は全て副作用。

以下は純粋なコンポーネント

const Hello1 = (props) => {
return <p>Hello, {props.target}!</p>

ただし、関数コンポーネントでは、各種のhooks呼び出しはしても良いとされている。
(関数コンポーネントの)純粋性というのはReactに独特な概念、つまりReactの慣習の一部。
では、純粋だと何がいいのか、純粋性を守ることで得られる恩恵は何か。

以下は純粋ではないコンポーネント。
このコンポーネントは親コンポーネントが再レンダリングすると一緒に再レンダリングされるため、自身と関係ないステートの変化に伴ってRenderCountの表示が変わってしまう。

let count = 0;
const RenderCount = () => {
count++;
return <p>{count}</p>

以下も純粋ではないコンポーネントの一例

const LoginComplete () => {
gtag('event, 'login'); // Google Analyticsにログイン完了を通知する関数
return <p>ログイン完了しました</p>

このような実装にすると、1回のログインで複数回の「イベントが送信されてしまう恐れがある。
この場合、以下のようにすると良い。

const LoginComplete = () => {
useEffect(() => {
gtag('event, 'login');
}, []);

React18について

主な機能はConcurrent RenderingSuspense

Concurrent Renderingにより、非同期的にレンダリングされるコンポーネントという概念が導入された。
外部と通信した結果が返ってきてからレンダリング結果を出力する、というようなコンポーネントを作ることができるようになった。
また、Suspenseによって、useQueryなどのisFetchingやisLoadingを見てLoadingコンポーネントを出し分けるといった実装をする必要がなくなり、より宣言的なコードを書けるようになった。

SuspenseのおかげでSSRもより良いものになっている。
Suspenseがあることで、いつコンポーネントのデータ取得が完了したか明確になった。
そのため、データ取得のロジックをコンポーネント内で完結させたまま、アプリケーションをSSR対応させることが可能になった。

Streaming SSR

SSRとCSRのいいとこ取りができるようになった。
具体的には、クライアント側でJavascriptを実行する必要がないという利点を保ったまま、CSRでやるようなRーディング中の画面をユーザーに見せることが可能になった。
流れとしては、まずローディング中の画面を含むHTMLをクライアントに送り、サーバー側でデータ取得が完了したらローディング後のHTMLを追加で送る。

これによって、SSRでのデメリットであったTTFB(Time to First Byte)が改善され、UXにも良い影響を与える。

Discussion