2021/08/16

Reactのjsxってなんなん?

@ 酒井悠宇

React

Reactのjsx。JavaScriptなのになんかHTMLっぽく書けていい感じ!くらいの理解度なので、りあクトを軽く復習していきまーす!

なぜReactはJSXを使うのか

そもそもJSXとは?

  • JSXという名前は、「JavaScript」と「XML」の組み合わせ。
  • JSXはXMLライクな記述が記述ができるようにしたES2015に対する拡張構文。


HTMLとは「Hyper Text Markup Language」の略です。Webページを記述するための表示用言語で、XMLと同じく文章中の文字列をタグで挟むことで、Webページに装飾を施すのが目的です。簡単にいうと、人間に情報をわかりやすく表示するための言語といえます。一方のXMLは、データ記述用の言語です。文書中のデータをわかりやすくしたり、データを交換したりできます。マシンに情報をわかりやすく、効率よく伝えるための言語といっても良いでしょう。

https://hnavi.co.jp/knowledge/blog/xml/

拡張構文:言語標準には含まれない特殊な用途のための便利な構文を、後づけで使えるようにしたもの


Jsxのコードはコンパイルした結果次のように変換される。

<変換前のJSXコード>

<button type="submit" autoFocus>
  Click Here
</button>;


<変換後のJavaScriptコード>

React.createElement(
  "button", //第一引数にタグ名
  { type: "submit", autoFocus: true }, //第二引数にProps
  "Click Here" //第三引数にchildren
);


尚、React 17.0からはパフォーマンス改善などを目的とした新しい変換形式が導入されている。
Create React App 4.0からもデフォルトの設定はこちらが有効になっているのでその変換結果は以下のようになる。

<変換後のJSXコード>

import { jsx as _jsx } from "react/jsx-runtime";
function App() {
  return _jsx("button", {
    type: "submit",
    autoFocus: true,
    children: "Click Here",
  });
}


JSXを理解するには従来の変換結果の方がわかりやすく、内部でやってることの本質は変わらないので、以降は従来型を前提にする。

React.createElementのメソッドコールは、実際には以下のようなオブジェクトを生成する。

{
  type: 'button',
  props: {
    type: 'submit',
    autoFocus: true,
    children: 'Click Here',
  },
  key: null,
  ref: null,
};


これは TypeScript では ReactElement というインターフェースを下敷きにしたオブジェクトとなる。
つまりJSXの構文は、本質的にはReactElementオブジェクトを生成するための式であるということ。

JSXはJavaScriptにおいては単なるオブジェクトを表現する式に還元されるものであり、特別な存在ではない。
なので、変数に代入したり、オブジェクトのプロパティの値にしたり、関数の引数や戻り値にすることもできる。

const element = <span>foo</span>;
const obj = { bar: element };
const wrap = (element) => <div>{element}</div>;


なぜReactは見た目とロジックを混在させるのか


Ruby on Rails等のサーバーサイドフレームワークは、そのほとんどがMVCを採用している。MVCとはアプリケーションを(model, view, controller)の3つの要素に分割して分ける方法。

MVCなどのアーキテクチャ、デザインパターンは、「関心の分離」を行う為にあるもの。
MVCでは、「技術の役割」によって3つに分解している。
modelはデータのやり取り、viewは見た目、controllerはリクエストに対する処理の振り分け。

Reactにおいては、関心の分離の単位がMVCのような技術の役割ではない。アプリケーションの「機能」がその単位になっている。
機能単位で分割された独立性の高いパーツを組み合わせることでアプリケーションを構築しようというのが、Reactの開発思想。
そのパーツが「コンポーネント」

独立した機能単位のパーツとして分割する為には、そのパーツの中に見た目とロジックを閉じ込める必要がある。
そうでなければパーツ同士が疎結合にならない。

Railsであればそのページに必要な処理をcontrollerが全部終わらせてからviewページ全体をまとめてレンダリングするのにに対して、Reactはコンポーネント自身が自身の描画に必要な処理を自分でやり、レンダリングもコンポーネントごとに個別で行われる。そしてそれらはコンポーネント単位で並列に非同期で実行される。

Web版のTwitterとかはまさにReact製。各コンポーネントが自律的にTwitter APIと通信してデータを取得し、個別にレンダリングする為「ページ全体のレイアウトはすでにレンダリングされているのに、部分的にデータの取得待ちでローダーがぐるぐる回る」というったことが起きる。


はい、本日二本目の記事ですがりあクトを軽く復習しました !

  • JSXが内部的にはReactElementオブジェクトを作るReact.createElement();のメソッドコールだったこと。
  • JSXを変数に代入したり、関数の引数や戻り値にできること

この辺はなるほどって感じでした。
最後までごらんいただきありがとうございました!

© 2021 powerd by UnReact