ホーム自己紹介ブログ
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 の処理が重たいときに
フロントエンド

-

シェアする

フォローする

次のページ

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

前のページ

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

関連する記事

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

ヒューマンインターフェース ガイドライン という言葉を知りました。

最近、ヒューマンインターフェース ガイドライン(HIG)という言葉を知りました。 「ヒューマンインターフェイスガイドライン」には、どのAppleプラットフォームでも優れた体験を設計できるようにするためのガイドとベストプラクティスが含まれてい

2026-01-24

フロントエンド
AIの利用上限に達した時にすることを残しておく

主にWeb関連の個人開発をしている際に心がけていることを書きます。 月末に近づくにつれ、AIの利用上限に達してしまうことがあります。 その状況になった時、以下のいずれかの選択肢が私の中では残っています。 課金して利用上限を増やす 無料モデル

2026-01-22

フロントエンド
AI
CSSで頑張らなくても、SVGで楽にできるときもある

個人サイトをリニューアルをしています。 ノート風のデザインを目指して、スタイルを調整していました。 ノートの見た目は、現実にあるノートを再現しようとCSSを書いていました。 現在、以下の画像のようなノートになっています。 ノート風デザインの

2026-01-20

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