LoginSignup
0
0

More than 1 year has passed since last update.

React開発Part1~JSX記法、render()編~

Last updated at Posted at 2023-03-19

はじめに

 おはようございます、Tunです。
今回は、前回の続きでReactの基礎編を復習がてらに記載していきたいと思います。

JSX記法、render()関数

 まず初めに抑えておきたいのはJSX記法というReactの書き方の基本となるものです。これはJavaScriptのファイルの中でHTMLのタグのような書き方ができるというものです。公式ドキュメントには、「JSXとはReact.creatElement(component, props,...children)糖衣構文にすぎない」と書かれています。
※糖衣構文(syntax suger)・・・難しく複雑な書き方を、簡単な書き方でも実現できる構文のこと

 さっそく、例を見てみましょう。

JSX
<MyButton color = "bule" shadowSize = {2}>
  Click Me
</MyButton>

 これが以下のようにコンパイルされています。

React.createElement(
  MyButton,
  {color: 'bule', shadowSize: 2},
  'Click Me'
)

 Reactで開発するときは、JSX記法で記述しますが、コンパイル後の書き方も念頭に置いていた方がよさそうです。
 また、JSX記法にルールがあります。以下の例を見てみましょう。
※下記の他に、idにrootを持つdivタグが記述されているindex.htmlがある前提です。

index.js
import ReactDOM from "react-dom";

const App = () => {
  return (
    <>
      <h1>Hello!</h1>
      <p>How are you?</p>
    </>
 );
};

const container = document.getElementById("root");
ReactDOM.render(<App />, container);
  • react-domからReactDOMという名前でモジュールをimportする。
  • 関数Appを定義し、アロー関数を記述する
  • returnを書く
  • その中に処理を記述する(HTMLのタグが今回の処理部分)
  • render()関数を用いて、指定した要素の中のDOMにレンダリングし、そのコンポーネントへの参照を返す

 ここで、returnのあとに<></>で括られていますが、これがJSX記法のルールです。この他にもdivやReactで準備されているFragmentでもいいのですが、不要なDOMを生成させないためにも空タグで囲むのが無難かもしれません。
 また、Appを<>で括るのは、コンポーネントとして扱うためです。

render()関数について深堀~
公式には下記のような記述があります。

  1. Triggering a render
  2. Rendering the conponent
  3. Committing to the DOM

 ReactDOM.render()はReactDOM(react-domモジュール)からimportすることで使用でき、render(element, container[, callback])のように記述します。
 上記は、レンダーをトリガーとして、過ぎにコンポーネントにレンダーし、最後にDOMにコミットする、というような流れです。
 ですので、render()関数の役割については、レンダリングの結果で差分があるか否かの判断をするために、互いのdifferenceを検出することだと解釈しています。

だがしかし!!!!

時代の流れというものは早いもの、この書籍を購入してから今までの間、Reactはv18にまでアプデしており、ReactDOM.render()についてはレガシーな書き方になってしまった!

公式でも、

renderはReact18でcreateRootの置き換わりました。詳細はcreateRootを参照してください。

と言っていました...
ってことで、ReactDOM.render()がReact18でcreateRoot().render()に置き換わったということで、以下これで書き直して解説していきます。

まず、createRoot()の書き方ですがcreateRoot(container[, options]);というように記述します。渡されたcontainerに対するReactルートを作成してそれを返します。rootのrenderを使ってDOM内部にReact要素をレンダーします。

createRoot()
const root = createRoot(container);
root.render(element);

これを踏まえて上記の例を書き換えてみましょう。

App.jsx
export const App = () => {
  return (
    <>
      <h1>Hello!</h1>
      <p>How are you?</p>
    </>
 );
};
index.js
import { createRoot } from "reacr-dom/client";
import App from "./App";

const container = document.getElementById("root");
const root = createRoot(container); //← 増加
root.render(<App />);

 いきなりApp.jsxが出てきたぞ...という方
これがReactの醍醐味と言える関数のコンポーネント化というもので、コンポーネントファイルの拡張子は.jsxと書き、JavaScriptのファイルと見分けがつくようにしています。このApp.jsxを他のファイルでも使えるようにexportしておきます。
 次に、index.jsにApp.jsxを取り込みます、これはimportで行います。またcreateRoot()を使うには、react-domからではなく、新たなreact-dom/clientからimportします。この際に、{ }で取り込んでいますが、これは別名ではなくReactDOMClientから提供されている関数を取り込んで名前をそのまま使いますよ、という意味です。{ }なしでは自分の好きな名前で定義して、ReactDOMClient自体を取り込みます。
 ReactDOMよりも一文増えたかのように思えますが、ではcreateRootを追加うメリットはあるのかという疑問が芽生えます。
 調べたところ、v18から並行処理の機能群にアクセス可能になったようです。この並行処理は、レンダリング途中でもユーザが操作でき、UXが向上するメリットがあるようです。React公式
 今後、UXも重要になってきますので、開発コストを鑑みて導入を検討を加速させ、検討に検討を重ね、慎重に検討されてはいかがですか?

 長くなりましたので、Part2はpropsから入りたいと思います。

参照

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