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

-

読者になる

|

シェアする

|

silverbirders

silverbirder

Webソフトウェアエンジニア
個人ブログキュレーション こぶりー 運営

ブログを応援する

この記事がよかったら、お布施という形で応援してもらえるとうれしいです。

おふせぼたん

※ ログイン不要で投稿できます。

※ 同じブラウザから投稿を削除できます。

0

読み込み中...

次の記事へ前の記事へ

関連する記事

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

Webmention 使ってみた

Webmention というのを最近知りました。 名前の通り、Web 上でメンションすることができます。 受信側、送信側、どちらも対応したので感想を残そうと思います。 Webmention ざっくりと Web AサイトにBサイトのリンクをつ

2026年09月08日

フロントエンド
個人開発
モジュールアップデートでやっていること

ITヲタクな AI くんにピッタリな仕事の一つは、モジュールアップデート。 特に、メジャーアップデートが超助かる。 昔だったら 数ヶ月掛かった移行も、数日たらずに対応できるようになったので、 さすが ITヲタクくん。 対応してよかったフロー

2026年07月24日

AI
フロントエンド
写経テストコードを全部消した

以下で書いた通り、プロダクトコードを写経したテストコードを削除しました。 "こぶりー" ( https://kobliy.vercel.app/ ) という個人ブログを読むアプリのコードです。 https://silverbirder.gi

2026年06月08日

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