はじめに
Reactはユーザインタフェース構築のためのJavaScriptライブラリです。次のような利点があるため、HTML、CSS、 jQuery を学習し、Web制作者目指しているような方もReactにも興味を持つと良いと思いました。JavaScriptをある程度学習していれば、Reactはそんなに難しくないからです。
- コンポーネントベース
- ブロックを組み立てるようにユーザインタフェースを構築できる
- 見通しがよく、苦痛が少ない
- 一度学習すれば応用が効く
- サーバー上でもレンダーできる
- モバイルアプリケーションの中でも動く(React Native)
Reactを二ヶ月くらい学習し、真似してコードが多少書けるようになった時、私はそのコードにどうにも腑に落ちませんでした🥺。その頃の私はReact以前にJavaScriptがよくわかっていなかったのです。そんな少し前の自分に説明するつもりで書いてみた記事になります。
サンプルコード1
このサンプルは[Toggle]ボタンをクリックするたびに、ボタンの上の絵文字が👍と👎の間で切り替わるという簡単なものです。
import React, { useState } from "react";
const App = () => {
const [liked, toggleLiked] = useState(false);
const handleToggle = () => toggleLiked(!liked);
return (
<>
<p>useState Sample #1</p>
<p>{liked ? "👍" : "👎"}</p>
<button onClick={handleToggle}>Toggle</button>
</>
);
};
export default App;
今の自分「useState(ステートフック)を使用しています。シンプルで何の問題もないですね。」
昔の自分「なんだか、わかったようなわからないような。すっきりしないのです🥺。そもそもフックってどういうこと?意味があまりわからないです🥺。」
今の自分「フックは何種類かあるのですが、ステートフックとはクラスコンポーネントでは普通に持つことができるステート(コンポーネントがその内部に変数のように持つオブジェクト)をファンクショナルコンポーネント(関数コンポーネント)にも持たせられるようにするための関数です。それでは、次のコードはわかりますか?」
サンプルコード2
こちら見た目や動きは先程のものと同じです。コードの行数は16から36(うち3行はコメントだけの行)と倍増しました。
import React from "react";
export default function App() {
const stateArray = React.useState(false); // stateArray[0]の初期値をfalseにする
// 戻り値は以下の配列
// stateArray[0]: true(👍) または false(👎)が入る
// stateArray[1]: stateArray[0]を設定する関数
let liked = stateArray[0];
const setLiked = stateArray[1];
function handleToggle() {
if (liked === true) {
setLiked(false);
} else {
setLiked(true);
}
}
if (liked === true) {
return (
<div>
<p>useState Sample #2</p>
<p>👍</p>
<button onClick={handleToggle}>Toggle</button>
</div>
);
} else {
return (
<div>
<p>useState Sample #2</p>
<p>👎</p>
<button onClick={handleToggle}>Toggle</button>
</div>
);
}
}
昔の自分「コードが長くなりましたが、大分親しみやすいコードです。React.useSateが要素数2の配列を返し、0番目の要素が設定した値の参照用。1番目の要素が、その値を設定する関数を指し示すわけですね。」
今の自分「サンプルコード1(StackBlitz)の以下の部分は、Reactライブラリのエントリポイント(名前空間)のReactをインポートし、Reactの中にあるuseStateを特定の名前付きでインポートをしています。この辺りの詳細はこちらを見てください。」
import React, { useState } from "react";
今の自分「サンプルコード1(StackBlitz)の以下の部分は、分割代入(Destructuring assignment)という構文で、配列から値(あるいはオブジェクトからプロパティ)を取り出して、別個の変数に代入できる書き方になります。
const [liked, toggleLiked] = useState(false);
昔の自分「アロー関数は知っているのですが、Appという関数の中に handleToggleという関数があるのはどういうことでしょうか?」
今の自分「これはクロージャというやつです。マトリョーシカ人形の親子で例えると、親(関数)から子(関数)の心の内(子の変数など)は見ることができませんが、子からは親の心の内(親の変数など)を見ることができる仕組みです。」
昔の自分「なるほど。この辺り、Reactの話しではなくて、全部JavaScriptの話ですね?」
今の自分「そのとおりです。そして、return で返しているHTMLみたいなタグ構文はJSXと呼ばれるJavaScriptを拡張した書き方です。」
昔の自分「それは教材で習いました。これがコンパイルされて、ブラウザで実行可能なコードに変換するのでしたね?」
今の自分「そうです。上のコードはReactのライブラリの関数を1つ呼んでいることと、JSXが使われている以外は表面上はただのJavaScriptとして理解できます。」
Reactを少し勉強してみて感じたこと
1. JSXを用いたUIコンポーネント作成は楽しくてわかりやすい
- 見通しよく作成でき、他人と分担もしやすいです
<Navbar />
<TodoList />
<Footer />
2. 親コンポーネントが子コンポーネントに props を渡す方法は1方向で単純でわかりやすい
- 渡した値は変更されない決まり
- 親が子に関数を渡して子から呼んでもらうことなどができる(コンポーネントに関数を渡す)
3. ファンクショナルコンポーネントはクラスコンポーネントよりシンプルで書きやすい
- これから作るだけならファンクショナルコンポーネントだけでよいと思います
- 必要ならファンクショナルコンポーネント以下のフックを組み合わせるなどして、ローカルステート、グローバルステート、ライフサイクルを扱うなど、クラスコンポーネントと同じようなことができる
4. BabelやWebpackとかのややこしい設定は不要
- Create React AppやNext.jsやGatsbyを使えば知る必要がない
- 環境構築で悩む必要なし
- それらについて概要はこちら
5. CSSは好みに合わせて色々な書き方ができる(CSS とスタイルの使用)
- 個人的にはstyled-componentsが良さそうに思っていますが、賛否両論あるみたいですね。