0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【第十四回】コンポーネントもReact要素

0
Posted at

前回の最後に、コンポーネント自体はReact要素なのかという疑問を投げかけました。今回はそれを実際に確認していきます。

結論から言うと、コンポーネントもReact要素です

変換結果を見てみる

まず、HTMLタグの場合はこうでした。

<h3>Hello World</h3>
_jsx("h3", { children: "Hello World" });

では、Greet.tsxのようにコンポーネントを読み込んだ場合はどうなるでしょうか。

//Greet.tsx
const Greet = ()=> {
  return (
    <div className="component">
      <List color="red" />
    </div>
  );
}
_jsx("div", {
  className: "component",
  children: _jsx(List, { color: "red" }),
});

childrenのところに、Listコンポーネントの_jsx()が設定されています。

React要素とは「この関数によって作成されるオブジェクト」のことなので、コンポーネント自体も最終的にはReact要素に変換される、ということが分かります。

コンソールで確認する

実際にコンソールで見てみましょう。

//Greet.tsx
import "./Greet.css"
import List from "./List"
const Greet = ()=> {
  const sample = (
    <div className="component">
      <List color="red" />
    </div>
  );

  console.log(sample);

  return sample;
}

export default Greet;

一番上の階層はdivタグなので、typedivになっています。

そしてpropschildrenのところにListコンポーネントが設定されているはずです。開いてみましょう。

typeのところに関数が設定されていて、nameにはListと入っています。これは関数コンポーネントの名前です。

つまりHTMLタグのときはtype"div"のような文字列が入り、コンポーネントのときはtype関数そのものが入るわけです。

Reactはこの関数を実行し、返ってきたTSXがまたReact要素になって、という再帰的な構造をとっていきます。

React要素のツリーで考える

いま作っているアプリの構造を思い出してみましょう。

//page.tsx
import Greet from "../components/Greet";
const Home = ()=> {
  return (
    <Greet />
  );
}

export default Home;

HomeGreetを読み込み、GreetListを読み込んでいます。このときのReact要素のツリーはこうなります。

Home のReact要素
└── Greet のReact要素
    └── div のReact要素
        ├── h3 のReact要素
        └── List のReact要素
            └── ul のReact要素

1つ1つの要素がReact要素であり、そこにはTSXのタグから作られるReact要素コンポーネントから作られるReact要素が混在しています。

ですのでReactの内部では、コンポーネントもReact要素として扱っているということを覚えておいてください。

コンポーネントツリー

なぜこれをわざわざ紹介したかというと、コンポーネントを含むこのツリーのほうが、React内部で保持されているデータ構造により近い形になるためです。

先ほどのツリーから、コンポーネントだけを抽出するとこうなります。

Home
└── Greet
    └── List

このコースでは、

  • React要素のツリー
  • そこからコンポーネントだけを抽出したコンポーネントツリー

この2つを使ってReactの挙動を説明していきます。コンポーネントツリーという単語は以降よく出てくるので、ぜひ覚えておいてください。

余談:Fiber

ここからは余談なので、力を抜いて読んでいただければと思います。

Reactの内部では、React要素のツリーから作成したFiberツリーという別のツリーを用いて状態管理を行っています。その1つ1つの要素はFiberノードと呼ばれ、React要素とほぼ1対1の関係になります。

少し難しい内容ですし、覚えなくてもReact自体は問題なく使えるようになります。興味のある方はReact Fiberという単語で調べてみてください。

確認問題

以下の3つのファイルがあるとします。

//page.tsx
import Greet from "../components/Greet";
const Home = ()=> {
  return (
    <Greet />
  );
}

export default Home;
//Greet.tsx
import Container from "./Container"
import List from "./List"
const Greet = ()=> {
  return (
    <div className="component">
      <Container>
        <List />
      </Container>
    </div>
  );
}

export default Greet;
//Container.tsx
const Container = ({ children }: ContainerProps)=> {
  return (
    <div className="box">{children}</div>
  );
}

export default Container;

問題

  1. <Container>が変換されたあとの関数呼び出しを書いてください
  2. そのReact要素のtypeには何が入るか答えてください
  3. このアプリのコンポーネントツリーを書いてください

(下に解答を記載しています)

解答

1. 変換後の関数呼び出し

_jsx(Container, { children: _jsx(List, {}) });

2. typeに入るもの

Containerという関数そのものが入ります。

HTMLタグのときは"div"のような文字列が入りますが、コンポーネントのときは関数が入る、というのが違いです。

3. コンポーネントツリー

Home
└── Greet
    └── Container
        └── List

React要素のツリーにはHTMLタグ由来のdivulも含まれますが、そこからコンポーネントだけを抽出するとこの形になります。

チェックリスト

  • コンポーネントもReact要素になると説明できる
  • HTMLタグはtypeが文字列、コンポーネントはtypeが関数だと区別できる
  • React要素のツリーには、タグ由来とコンポーネント由来の要素が混在している
  • Reactが関数を実行し、返ってきたTSXを辿っていく再帰的な構造を理解している
  • コンポーネントツリーがReact要素のツリーからコンポーネントだけを抜き出したものだと分かっている
  • コンポーネントツリーという単語を以降のレクチャーで使うと知っている
  • Fiberという仕組みがあることを名前だけ知っている

第十四回はここまで。
次回はこのセクションで学んだ内容を踏まえて、より深掘りをしていきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?