現在、作成中のチャットアプリで、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
BabelとJSXの使用
上記の app.js で、const template = React.createElement … という複数行のコードがありますが、これをJSX(JavaScript XML)というシンプルだけどHTMLみたいなヘンテコな次のような書き方をできるようにします。
const template = <h1 id="someid">ハローReact!</h1>;
これを可能にするのがBabelです。ある書き方を実際のブラウザで解釈可能なように変換してくれるツールです。
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);
ブラウザは自動的に次に変わります。
便利なワークフローですね。
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);