ホーム自己紹介ブログ
NO.80
DATE2022. 06. 25

[覚書]Reactを業務で使い始めて知ったこと

私は、これまでプライベートでしか React を使っていませんでした。 最近、業務で React を使う機会が増えたので、学んだことを残そうと思います。

React の歴史

なんで React って生まれたんだろうって気になりました。 簡単ですが、ちょこっとだけ調べて、次の記事にまとめました。

  • React を学ぶ前に歴史を知る

React は、次の問題を解決したかったんだと思います。

  • DOM ツリーが大きくなるにつれて、下位の変更によるカスケード更新の負荷が大きくなる

そこで、React は、この問題を解決するために、仮想 DOM という仕組みを作ったんだと思います。

仮想 DOM、差分検出処理、そして Fiber

React は、直接 DOM を操作するのではなく、仮想 DOM に対して操作します。仮想 DOM は、名前の通り仮想的な DOM です。 仮想 DOM を DOM へ反映するために、差分検出処理(reconciliation)というアルゴリズムがあったり、Fiber と呼ばれる、レンダリングの最適化(優先順位)を目的としたアルゴリズムもあるようです。これらのおかげで、レンダリング負荷が軽減されるんだと思います。(しらんけど)

まだまだ理解が浅いので、これからもっと学んでいきたいと思います。

  • 仮想 DOM と内部処理 – React
  • 差分検出処理 – React
  • acdlite/react-fiber-architecture: A description of React's new core algorithm, React Fiber
  • React Fiber アーキテクチャについて | POSTD

レンダリングのタイミングは、いつなんでしょうか。

レンダリングタイミング

基本的に、React は、親コンポーネントをレンダリングすると、子コンポーネントもレンダリングされます。

再レンダリングをキューイングする関数、setState や forUpdate などを呼ぶと、コンポーネントはレンダリングされることになります。

  • Blogged Answers: A (Mostly) Complete Guide to React Rendering Behavior · Mark's Dev Blog

コードベースが大きくなるにつれて、レンダリングのパフォーマンスが悪化していきます。 そこで、パフォーマンスの最適化が求められます。

パフォーマンス最適化

最初からパフォーマンス最適化をする必要はありませんが、要件によっては必要になることもあります。 最適化の手段として、React にある、次の 3 つの関数が使えます。

  • memo
    • コンポーネントのレンダーをスキップできる
      • 以前の props と現在の props で変更がなければ
  • useMemo
    • 値をメモ化できる
  • useCallback
    • 関数をメモ化できる
      • memo と併用して使う

パフォーマンス最適化 – Reactも参考になります。

比較アルゴリズム

React では、コンポーネントや状態が変更されたかどうかの判定に、Object.is() を使っているようです。 Object.is のサンプルコードは、次のとおりです。

Object.is("foo", "foo"); // true
Object.is("foo", "bar"); // false
Object.is([], []); // false
 
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false

string や integer のようなプリミティブな値は良いのですが、非プリミティブな値(Object)の場合の考慮が必要です。 例えば、memoの場合は、第二引数に比較関数を渡すことができます。 例えば、次のような感じです。

function MyComponent(props) {}
function areEqual(prevProps, nextProps) {
  return JSON.stringify(prevProps.foo) === JSON.stringify(nextProps.foo);
}
export default React.memo(MyComponent, areEqual);

公式ページにも書いていますが、パフォーマンス最適化のみに使いましょう。

Tips

Object.is() を使われている影響で、非プリミティブな値の状態更新に、工夫が必要です。

const [items, setItems] = useState(["a", "b"]);
 
// NG
items.push("c");
setItems(items); // 変更されない(Object.is()→true)
 
// OK
const newItems = [...items, "c"];
setItems(newItems); // 変更される(Object.is()→false)

NG の方は、同じオブジェクトを使いまわしているのに対し、OK の方は、新しくオブジェクトを生成しています。

パフォーマンス調査

トップダウンでパフォーマンス調査をするのが、ベターと思います。

  1. Chrome Developer Tools > Lighthouse を使い、performance score を確認
  2. Chrome Developer Tools > Performance を使い、処理に時間がかかっている箇所を見つける
  3. React Developer Tools > Profiler を使い、React コンポーネントのレンダリングで時間がかかっている箇所を調査

React コンポーネント デザインパターン

React でコンポーネントを実装していると、次の 3 つのパターンがあるようです。

  • Container and presentation
    • ロジックと UI を分離
    • XxxContainer, Xxx という命名が多い
  • Higher order component
    • 高階コンポーネント
    • withXxx という命名が多い
  • Function as child
    • コンポーネントではなく関数を child として渡す

ロジックを独自フックとして切り出す

テスタビリティや再利用性の観点より、ロジックを hooks として切り出すのが良さそうです。

  • 独自フックの作成 – React

命名は、use から始まることが多いです。

その他

  • コンポーネントコードと同じフォルダ内に、次のファイルを置きたい
    • テストコード (test)
      • 仕様を知る
    • カタログコード(storybook)
      • UI を見る
    • スタイルコード (scss)
  • input 要素などの onChange には、debounce を使う
    • onChange の処理が重たいときに
フロントエンド

-

コメント

0

読み込み中...

シェアする

フォローする

購読する

次のページ

学生時代に経験したアルバイト

前のページ

Micro Frontendsで組成するフラグメントをWeb Componentsで定義してModule Federationで共有する

関連する記事

タグ「フロントエンド」の記事

AIの書いたコードの手直しを減らすお作法

AI にコードを書かせた後、余計なコードを見つけて消す作業があります。 不毛なことなので、それらの作業を減らすためのお作法を紹介します。 未使用コードを消す 以下でも書きましたが、未使用コードの検査に knip を使うことが多いです。 ht

2026年02月25日

AI
フロントエンド
iframeの難しさ

最近、iframeを使っています。 クライアントサイドで埋め込む想定で、iframeを使おうとしています。 色々と苦労したことがあったので、書いて残しておこうと思います。 レスポンスヘッダー 前提として、ウェブアプリケーションをプロダクショ

2026年02月18日

フロントエンド
ブラウザ
SVGを書くと数学の知識が必要だった

紙を積んだイラストをSVGで書こうとしていました。 (当たり前ですが)図形を表現するためには数学の知識が必要で、学生の頃の記憶を思い出したので疲れました。 所感について、諸々書こうと思います。 成果物 実際に完成したのは、以下の画像ができま

2026年02月17日

フロントエンド
← ブログ一覧へ