React入門 その① 開発環境の構築とJSX

2019-12-31

現在、作成中のチャットアプリで、mustache.js というテンプレートエンジンを使用しているのですが、シンプル過ぎて逆にReact試してみたくなりました。

まだ、入門3晩目なのですが、割といい感じです。

開発環境の構築

以下をインストールします。

> npm install -g yarn
> yarn --version // インストールしたバージョンを確認

加えて開発を便利に進めるため yarn 又は npm を用いて live-server をインストールします。

yarnの場合

> yarn global add live-server
> live-server -v // インストールしたバージョンを確認

npmの場合

> npm install -g live-server
> live-server -v  // インストールしたバージョンを確認 

Hello world

まずはお決まりの Hello world 的なものを作ります。

publicフォルダにhtmlファイルを作り、bodyタグに以下を書きました。

以下のパスの最新はこちらから調べられます。

 <!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello World</title>
</head>
<body>
    <div id="app"></div>
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="/scripts/app.js"></script>
</body>
</html> 

app.js には次のようなコードを書きます。

const template = React.createElement("h1", {
    id: "someid"
  }, "ハローReact!");
const appRoot = document.getElementById('app');
ReactDOM.render(template, appRoot); 

live-server は次のようにフォルダ(この場合、public)を指定して、起動します。

> live-server public
Hello World

BabelとJSXの使用

上記の app.js で、const template = React.createElement … という複数行のコードがありますが、これをJSX(JavaScript XML)というシンプルだけどHTMLみたいなヘンテコな次のような書き方をできるようにします。

const template = <h1 id="someid">ハローReact!</h1>;

これを可能にするのがBabelです。ある書き方を実際のブラウザで解釈可能なように変換してくれるツールです。

BabelTry it outというページで、この変換について試すことができます。

Babelの Try it out

Babelのインストールと設定

BabelのCLIツールのインストールは次のいずれかのコマンドによりおこないます(バージョンを指定する場合)。

> yarn add babel-cli@6.24.1 // 今もっと新しいのあります
又は
> npm install babel-cli@6.24.1 

使い方は次のコマンドで調べる事ができます。

> babel --help

続いて、package.json ファイルを生成させてから、yarn のプリセットをおこないます。

> yarn init // 質問されるがすべてEnterキーを単に押し続ける。
> yarn add babel-preset-react babel-preset-env

1行目のコマンドで package.json が作られ、2行目のコマンドで package.json に以下の部分が追加されます。yarn.lock というファイルも作られますが、これは編集しないようにします。

:
  "devDependencies": {
    "babel-cli": "6.24.1",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "live-server": "^1.2.1" 
}  

Babelによる変換

最初の Hello world的なやつで、public/scripts/app.js というファイルを用いましたが、新たにJSXを記述する src/app.js を作り、そこから古い形式のJavaScritによる public/scripts/app.js を生成させるようにします。

const template = <p id="someid">ハローReact!</p>; // ここをJSXにしました。
const appRoot = document.getElementById('app');
ReactDOM.render(template, appRoot); 

変換は下記のようなコマンドにより実行します。

> babel src/app.js --out-file=public/scripts/app.js --presets=env,react

コードの変更を即座にブラウザに反映させる方法

コードを変更したときに、いちいち Babel のコマンドを再実行せずとも、自動的にブラウザでの表示に反映させるためには、次のようにします。

① 1つめのターミナルにて下記のコマンドを実行しておく。

> babel src/app.js --out-file=public/scripts/app.js --presets=env,react --watch

② 2つめのターミナルにて下記のコマンドを実行しておく。

 > live-server public 

これにより、src/app.js が変更されると、自動的にそれを検出して、public/scripts/app.js が生成され、ブラウザの表示が更新されます。

例えば、src/app.js を次のように変更すると・・・

const template = <h1 id="someid">ハローワールド</h1>;
const appRoot = document.getElementById('app');
ReactDOM.render(template, appRoot); 

public/scripts/app.js が次に変更され・・・

“use strict”;
var template = React.createElement(  “h1”,  { id: “someid” },  “\u30CF\u30ED\u30FC\u30EF\u30FC\u30EB\u30C9”);var appRoot = document.getElementById(‘app’);ReactDOM.render(template, appRoot);

ブラウザは自動的に次に変わります。

Hello world

便利なワークフローですね。

JSXを更に学習

JSXでは次のように書くとエラーになります(エラーがターミナルに表示されます)。

 const template = <h1 id="someid">ハローワールド</h1><p>これは情報です。</p>; 

次のように全体を一つのdivタグで囲ってあげればエラーが解消します。

 const template = <div><h1 id="someid">ハローワールド</h1><p>これは情報です。</p></div>; 

また、イコールの右側を括弧で囲い、次のように見やすく改行しても問題ありません。

const template = (
    <div>
        <h1 id="someid">ハローワールド</h1>
        <p>これは情報です。</p>
    </div>
); 

動的に更新

動的に更新されるWebサイトにするためには、変数やロジックが必要です。そしてデータはユーザーが入力したり、データベースから持ってきたりして、実用的なWebアプリケーションにすることができます。

変数はJSXに{変数}という形で書くことができます。また、条件分岐や論理演算子など書くことができます。

ここではサンプルとして次のようなページを作ってみました。

名前が指定されていなかったり、年齢が20歳未満であったり、住所データがなかったり、備考情報がなかったりの場合は、次のように表示するようにします。

このコードは次のような感じになります。

const user = {
    name: 'pitang1965',
    age: 54,
    location: '東京都いなか市',
    options: ['鼓膜が弱い', '紫外線に弱い']
}

// const user = {
//     age: 18
// }

const getLocation = (location) => {
    if (location) {
        return <p>住所:{location}</p>;
    } else {
        return undefined;   // 何も表示しない
    }
}

const getList = (lists) => {
    const listItems = lists.map((item) => <li key={item}>{item}</li>)
    return (<ul>{listItems}</ul>); 
}

const template = (
    <div>
        <h1>{user.name ? user.name.toUpperCase() : '名無しさん'}</h1>
        {(user.age && user.age >= 20) && <p>年齢: {user.age}</p>}
        {getLocation(user.location)}
        {(user.options && user.options.length > 0) && <div>備考:{getList(user.options)}</div>}
    </div>
);

const appRoot = document.getElementById('app');
ReactDOM.render(template, appRoot);