日本語版
最新ニュース
科学&テクノロジー

React のレベルアップ : React 要素を詳しく理解する

レベルアップリアクトシリーズについて Level Up React は、React 開発者のスキル向上を支援することを目的とした一連の詳細な記事です。 React の内部メカニズム、ベスト プラクティス、設計パターン、高度な概念を探ります。これらの記事は、基本を超えて React が内部でどのように動作するかを真に理解したいと考えている React 開発者向けに書かれています。 シリーズの前の記事 React のレベルアップ: 宣言型プログラミングと命令型プログラミング React 要素とは何ですか? React 要素は、ユーザー インターフェイス内のノードを記述する単純な JavaScript オブジェクトです。これは React の最小の構成要素です。その構造を見てみましょう。 // Basic structure of a React Element { $$typeof: Symbol.for('react.element'), type: 'div',…

React のレベルアップ : React 要素を詳しく理解する

1736967992
2025-01-14 12:18:00

レベルアップリアクトシリーズについて

Level Up React は、React 開発者のスキル向上を支援することを目的とした一連の詳細な記事です。 React の内部メカニズム、ベスト プラクティス、設計パターン、高度な概念を探ります。これらの記事は、基本を超えて React が内部でどのように動作するかを真に理解したいと考えている React 開発者向けに書かれています。

シリーズの前の記事

  1. React のレベルアップ: 宣言型プログラミングと命令型プログラミング

React 要素とは何ですか?

React 要素は、ユーザー インターフェイス内のノードを記述する単純な JavaScript オブジェクトです。これは React の最小の構成要素です。その構造を見てみましょう。

// Basic structure of a React Element
{
  $$typeof: Symbol.for('react.element'),
  type: 'div',
  key: null,
  ref: null,
  props: {
    children: 'Hello World'
  }
}

各プロパティを分析してみましょう。

$$typeof プロパティ

$$typeof: Symbol.for("react.element");

このプロパティは、React が他の JavaScript オブジェクトから React 要素を表すオブジェクトを識別するために使用する内部署名です。これは React の内部メカニズムであり、通常はコード内で直接処理する必要はありません。

タイププロパティ

type 要素の性質を決定します。

// 1. For native HTML elements
{
  type: "div"; // or 'span', 'p', etc.
}

// 2. For React components
{
  type: MyComponent; // direct reference to the function or class
}

// 3. For fragments
{
  type: Symbol.for("react.fragment");
}

小道具

props すべてのデータと要素のコンテンツが含まれます。

{
  type: 'button',
  props: {
    className: 'btn',
    onClick: () => console.log('click'),
    children: 'Click me'
  }
}

特別な children プロパティにはいくつかの形式があります。

// 1. A simple string
{
  props: {
    children: 'Simple text'
  }
}

// 2. Another React Element
{
  props: {
    children: {
      $$typeof: Symbol.for('react.element'),
      type: 'span',
      props: { children: 'Text in span' }
    }
  }
}

// 3. An array of elements
{
  props: {
    children: [
      { $$typeof: Symbol.for('react.element'), type: 'li', props: { children: '1' } },
      { $$typeof: Symbol.for('react.element'), type: 'li', props: { children: '2' } }
    ]
  }
}

key プロパティと ref プロパティ

{
  key: 'unique-id', // Used for list reconciliation
  ref: null // Can contain a reference to the DOM element or component
}

React はこれらの要素をどのように作成するのでしょうか?

JSX を記述する場合:

const element = div className="container">Hellodiv>;

Babel はそれを次のように変換します。

const element = React.createElement("div", { className: "container" }, "Hello");

React.createElement 次に、完全な React Element オブジェクトを構築します。

// Simplified pseudo-code of React.createElement
function createElement(type, config, children) {
  // Extract special props
  let key = config?.key || null;
  let ref = config?.ref || null;

  // Build props
  const props = {};
  for (let propName in config) {
    if (
      hasOwnProperty.call(config, propName) &&
      propName !== "key" &&
      propName !== "ref"
    ) {
      props[propName] = config[propName];
    }
  }

  // Handle children
  const childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    props.children = Array.prototype.slice.call(arguments, 2);
  }

  // Build the Element
  return {
    $$typeof: Symbol.for("react.element"),
    type,
    key,
    ref,
    props,
  };
}

入れ子になった要素

要素は複雑なツリーを形成できます。

// JSX
div className="parent">
  h1>Titleh1>
  p>Paragraphp>
div>

// Becomes the object
{
  $$typeof: Symbol.for('react.element'),
  type: 'div',
  props: {
    className: 'parent',
    children: [
      {
        $$typeof: Symbol.for('react.element'),
        type: 'h1',
        props: { children: 'Title' }
      },
      {
        $$typeof: Symbol.for('react.element'),
        type: 'p',
        props: { children: 'Paragraph' }
      }
    ]
  }
}

要素の調整

調整とは、React が 2 つの React Element ツリーを比較して、DOM に適用する変更を決定するプロセスです。

比較プロセス

React は要素を再帰的に比較します。

// Old Element
const oldElement = {
  type: "div",
  props: {
    className: "old",
    children: [
      {
        type: "p",
        props: { children: "Text" },
      },
    ],
  },
};

// New Element
const newElement = {
  type: "div",
  props: {
    className: "new",
    children: [
      {
        type: "p",
        props: { children: "New text" },
      },
    ],
  },
};

調整ルール

  1. 種類が違う場合:
// Old
{ type: 'div', props: { children: 'text' } }
// New
{ type: 'span', props: { children: 'text' } }
// → The old subtree is destroyed and a new one is created
  1. タイプが変わらない場合:
// Old
{ type: 'div', props: { className: 'old', children: 'text' } }
// New
{ type: 'div', props: { className: 'new', children: 'text' } }
// → Only the attributes are updated
  1. リストの場合:
// Old
[
  { type: "li", key: "1", props: { children: "one" } },
  { type: "li", key: "2", props: { children: "two" } },
][
  // New
  ({ type: "li", key: "2", props: { children: "two" } },
  { type: "li", key: "1", props: { children: "one modified" } })
];
// → React uses keys to identify elements that have moved

鍵の重要性

キーは、React がリスト内の各要素を識別するのに役立ちます。

// Without keys, React can't know if elements were reordered
// or replaced
[
  { type: "li", props: { children: "A" } },
  { type: "li", props: { children: "B" } },
][
  // With keys, React can track movements
  ({ type: "li", key: "a", props: { children: "A" } },
  { type: "li", key: "b", props: { children: "B" } })
];

スマート リコンシリエーションにより、React は DOM 操作を最小限に抑え、複雑なインターフェイスでも優れたパフォーマンスを提供できます。

結論

React 要素を理解することは、React 開発者にとって非常に重要です。これらの単純な JavaScript オブジェクトは、React のすべての基盤です。これらがどのように機能し、React がそれらをどのように使用するかを知ることで、以下のことをより深く理解できるようになります。

  • JSX がこれらのオブジェクトに変換される仕組み
  • React がリストに一意のキーを必要とする理由
  • React が調整を通じて DOM を効率的に更新する方法

複雑な React アプリケーションであっても、これらの基本的な構成要素から構築されることに注意してください。ほとんどの場合、React 要素を直接操作する必要はありませんが、その構造を理解すると、より適切な React コードを作成するのに役立ちます。

Level Up React のすべての記事は次の場所にあります。 https://www.56kode.com/tags/level-up-react/

#React #のレベルアップ #React #要素を詳しく理解する

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。