Jupyter Notebookで始める機械学習プログラミング
Python
PythonはWebアプリの開発からちょっとしたツールの開発まで、多目的に利用できるプログラミング言語です。また機械学習ライブラリが充実しているため近年注目を集めています。
次のAnacondaディストリビューションでPythonをインストールすることもできます。
Anaconda
Pythonで機械学習を始めるにはCONTINUUM社の配布しているはAnacondaディストリビューションを活用すると良いでしょう。以下のURLからダウンロートすることができます。
AnacondaにはPython本体だけでなく機械学習に必要なライブラリも梱包されているため、Anacondaをインストールすればすぐに機械学習プログラミングを始めることができます。
Jupyter Notebook
AnacondaにはJupyter Notebookというブラウザ上で動作するPython開発環境も付属しています。ターミナル(コマンドプロンプト)上で jupyter-notebook コマンドを実行するとローカルでサーバプログラムが起動し、ブラウザが起動します。
Jupyter Notebookの起動方法について補足しておきます。Anacondaインストール後、Windowsでは画面左下のWindowsメニューから「jupyter-notebook」とタイプするとアプリが見つかります。Macでは、ターミナル上でjupyter-notebookコマンドをタイプします。Jupyter Notebookはデフォルトで8888番ポートを使って起動します。ブラウザで http://localhost:8888/ にアクセスすると開発画面が表示されるでしょう。
Jupyter Notebookでは、ノートブックという形式でファイルを作成できます。ノートブックにはPythonコードや実行結果だけでなく、Markdown形式で文章を挿入することもできるので、データ分析の評価レポートを作成しやすいようになっています。またノートブックファイルは拡張子.ipynbという形式保存されます。.ipynbファイルはGitHubやGistなどでも表示できます。
クラウド上でJupyter Notebookを起動する
Jupyter Notebookの実体はブラウザで利用するWebアプリケーションです。そのためサーバ上でJupyter Notebookを起動すれば、手元のパソコンのブラウザからサーバ上でPythonプログラムを実行することも可能です。
ここではあらかじめJupyter環境をインストール済みのDockerコンテナを起動する方法を紹介します。またDeepLearning開発を支援するPaaS型サービスであるFloydHubを紹介します。
DockerでJupyter環境を構築するには
ここではクラウド環境としてAWSのEC2インスタンス(Ubuntu / Small)があるものとします。
sshでEC2インスンタンスにログインします。まずUbuntuのパッケージ情報を更新しておきます。
sudo apt update
次にDockerをインストールします。
sudo apt install docker.io -y
Dockerコンテナ(murayama333/ai-prog)を起動します。
sudo docker run -p 8888:8888 --name ai-prog -it murayama333/ai-prog
Dockerの出力ログにURLが表示されます。URLはlocalhostとなっているので、EC2のグローバルIPに置き換えてアクセスすると完了です。
ここで利用したDockerイメージはこちらの記事を参考に作っています。勉強になりました。
FloydHubで開発する
Dockerを使えばあっという間に開発環境を構築できますが、FloydHubを使えばもっと手軽にJupyter環境を整えることもできます。
FloydHub - Deep Learning Platform - Cloud GPU
FloydHubを一言で説明するなら
FloydHub is Heroku for DL
FloydHubはDeepLearningのためのHerokuです。つまり、DeepLearningのためのPaaS(Platform as a Service)です。FloydHubの素晴らしいところは、クラウド上ですぐに開発&実行ができるだけでなく、GPUインスタンスを利用することができる点です。無料アカウントの場合、GPUインスタンスは 2時間 / 月 まで利用できます。
FloydHub - Deep Learning Platform - Cloud GPU
FloydHub上でアカウントを作成後、開発キット(floyd-cli)をインストールします。
pip install -U floyd-cli
pipはPythonライブラリの追加コマンドです。pipコマンドを利用するにはローカルにPythonがインストールされている必要があります。
floydコマンドが有効になるので、FloydHubにログインします。
$ floyd login
以下、オフィシャルのクイックスタートを参考に動かしてみましょう。
https://docs.floydhub.com/getstarted/quick_start/
GitHubからサンプルのリポジトリをダウンロードしておきます。
git clone https://github.com/floydhub/quick-start.git cd quick-start
リポジトリの中のファイルの一覧を確認しましょう。
ls eval.py LICENSE mnist_cnn.ipynb README.md train_and_eval.py train.py
以降は、上記の train_and_eval.py プログラムをFloydHub上で実行してみます。
FloydHubプロジェクトを初期化します。
floyd init mnist-cnn
FloydHubでPythonプログラムを実行してみましょう。
floyd run --gpu --env tensorflow-1.3 "python train_and_eval.py"
ここでは --gpu オプションを指定してるので、GPUインスタンス上で実行されます。
FloydHubでJupyter Notebookを起動する
FloydHubのプロジェクトフォルダ上で(先のquick-startフォルダなど)、次のようにコマンドを実行します。
floyd run --mode jupyter Creating project run. Total upload size: 198.0B Syncing code ... [================================] 946/946 - 00:00:00 JOB NAME ----------------------------------- murayama333/projects/mnist-cnn/1 Setting up your instance and waiting for Jupyter notebook to become available ............. Path to jupyter notebook: https://floydlabs.com/notebooks/xxx
数秒(数十秒)でJupyterが起動します。
floyd run --gpu --mode jupyter
Jupyterを起動している間、GPUインスタンスの利用時間がカウントされるので、利用を終えたらインスタンスを停止しておきましょう。停止するときは JOB NAME(floyd run時のログを参照)を指定します。
floyd stop murayama333/projects/mnist-cnn/1
Reactだけ学ぶハンズオン
Reactだけ学ぶハンズオン
- Hello React・・・はじめてのReact
- Greeting・・・プロパティを学ぶ
- GreetingList・・・コレクションの考え方を学ぶ
- Echo・・・ステートを学ぶ
- Welcome・・・コンポジットなコンポーネントの作り方を学ぶ
昔の勉強会の資料です。内容古かったらすみません。
こっちのが見やすいかもです。
Reactだけ学ぶハンズオン 5/5
Part5 Welcome - ハンズオン
ここでは入力した内容を表示するReactアプリケーションを作成します。
開発は以下の手順で進めます。
1. ライブラリの設定
titleタグ以外は前章と同じです。ファイル名は05_welcome.htmlという名前で保存しておきます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 05</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> </script> </body> </html>
2. コンポーネント仕様を定義
ここでは以下のコンポーネントを作成します。
- Welcome
- GreetingList
- GreetingItem(*)
- Echo
- GreetingList
各コンポーネント仕様は次のようになります。
class GreetingItem extends React.Component { render() { } } class GreetingList extends React.Component { render() { } } class Echo extends React.Component { constructor(props) { } echo(e){ } isEnterKey(e){ } render() { } } class Welcome extends React.Component { constructor(props) { } save(completeName){ } echo(incompleteName){ } render(){ } }
コードが長くなるので順に見ていきましょう。まずはGreetingItemとGreetingListです。
class GreetingItem extends React.Component { render() { return ( <li>Hello {this.props.name}</li> ); } } class GreetingList extends React.Component { render() { var greetingItems = this.props.names.map(function(name, i){ return <GreetingItem name={name} key={i} />; }); return ( <div> <h1>Welcome to Webz</h1> <ul>{greetingItems}</ul> </div> ); } }
GreetingItem、GreetingListについては以前に作成した内容と同じです。GreetingListのnamesプロパティに名前の配列を設定することで、個々の名前が子要素のGreetingItemのnameプロパティに設定されます。
つづいてEchoコンポーネントです。
class Echo extends React.Component { constructor(props) { super(props); // bind this this.echo = this.echo.bind(this); this.isEnterKey = this.isEnterKey.bind(this); } echo(e){ this.props.onChange(e.target.value); } isEnterKey(e){ if (e.keyCode == 13) { this.props.onSave(e.target.value); } } render() { return ( <div> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} onKeyDown={this.isEnterKey} value={this.props.name}/> <h3>{this.props.name}</h3> </div> ); } }
Echoコンポーネントは以前に作成したものと以下の点で異なります。
- ステートnameではなく、プロパティnameを使用している
- echoメソッドの実装でステートの更新ではなく、onChangeプロパテイ(関数)を呼び出している
- onKeyDownイベントハンドラでisEnterKeyメソッドを呼び出している
1. ステートnameではなく、プロパティnameを使用している
Reactで、複合コンポーネントを作成する場合、可能な限りステートの管理は親コンポーネントで管理するようにします。
- Welcome
- GreetingList
- GreetingItem(*)
- Echo
- GreetingList
上記の場合、ステートはWelcomeコンポーネントで管理すべきです。従って入力中の名前を示すnameプロパティをWelcomeコンポーネントで定義し、代わりにEchoコンポーネントには、Welcomeコンポーネントとの外部インタフェースとなるnameプロパティを用意します。親コンポーネントのステートの変更をnameプロパティ経由で受け取るようにします。
render() { return ( <div> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} onKeyDown={this.isEnterKey} value={this.props.name}/> <h3>{this.props.name}</h3> </div> ); }
2. echoメソッドの実装でステートの更新ではなく、onChangeプロパテイ(関数)を呼び出している
Echoコンポーネントからnameステートを排除したので、echoメソッドの実装は次のようにonChangeプロパティを呼び出すようにします。
echo(e){ this.props.onChange(e.target.value); }
Echoコンポーネントを利用する親コンポーネント(今回の場合Welcomeコンポーネント)では次のようにプロパティを指定します。
<Echo name={this.state.name} onChange={this.foo} onSave={this.bar}/>
この場合、onChangeプロパティにWelcomeコンポーネントで指定したfooメソッドを指定してます。結果として、EchoコンポーネントでonChangeイベントが発生するとこのfooメソッドが呼ばれることになります。
3. onKeyDownイベントハンドラでisEnterKeyメソッドを呼び出している
onKeyDownイベントハンドラのisEnterKeyメソッドは次のようになっています。
isEnterKey(e){ if (e.keyCode == 13) { this.props.onSave(e.target.value); } }
キーコード:13とはEnterキーを意味しています。つまり、Enterキーが入力された場合、onSaveプロパティ(関数)を呼び出すようにしています。
たとえば、以下のようにEchoコンポーネントを定義しとしましょう。
<Echo name={this.state.name} onChange={this.foo} onSave={this.bar}/>
Enterキークリック時に、onSaveプロパティで指定されたbarメソッドが呼び出されることになります。
さいごに親コンポーネントとなるWelcomeのコンポーネント仕様を実装します。
class Welcome extends React.Component { constructor(props) { super(props); this.state = { names: this.props.names, name: "" }; // bind this this.save = this.save.bind(this); this.echo = this.echo.bind(this); } save(completeName){ var names = this.state.names.concat(completeName); this.setState({ names: names, name: "" }); } echo(incompleteName){ this.setState({name: incompleteName}); } render(){ return( <div> <GreetingList names={this.state.names} /> <Echo name={this.state.name} onChange={this.echo} onSave={this.save}/> </div> ); } }
constructorで初期ステートを指定します。ステートはnames配列と、name文字列の2つです。namesステートはGreetingListコンポーネントのnamesプロパティに指定し、nameステートはEchoコンポーネントのnameプロパティに指定します。
echoメソッド、saveメソッドはステートを更新します。これらのメソッドはEchoコンポーネントのイベントハンドラに指定しているので、Echoコンポーネントにおいて、イベントが発生時するとコールバックされます。
renderメソッドではGreetingListと、Echoコンポーネントをレンダリングしています。renderメソッドは単一のコンポーネントを返す必要があるので、divタグでラップしています。
3. コンポーネントクラスをレンダリング
作成したコンポーネントクラス(Welcome)を画面にレンダリングします。
var names = ["Murayama", "Takahashi", "Sanada"]; ReactDOM.render( <Welcome names={names} />, document.getElementById('example') );
Welcomeコンポーネントのnamesプロパティに3件の名前を指定します。こうすることで、画面描画時の初期値として表示されます。
ここまでの作業をまとめると次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 05</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> class GreetingItem extends React.Component { render() { return ( <li>Hello {this.props.name}</li> ); } } class GreetingList extends React.Component { render() { var greetingItems = this.props.names.map(function(name, i){ return <GreetingItem name={name} key={i} />; }); return ( <div> <h1>Welcome to Webz</h1> <ul>{greetingItems}</ul> </div> ); } } class Echo extends React.Component { constructor(props) { super(props); // bind this this.echo = this.echo.bind(this); this.isEnterKey = this.isEnterKey.bind(this); } echo(e){ this.props.onChange(e.target.value); } isEnterKey(e){ if (e.keyCode == 13) { this.props.onSave(e.target.value); } } render() { return ( <div> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} onKeyDown={this.isEnterKey} value={this.props.name}/> <h3>{this.props.name}</h3> </div> ); } } class Welcome extends React.Component { constructor(props) { super(props); this.state = { names: this.props.names, name: "" }; // bind this this.save = this.save.bind(this); this.echo = this.echo.bind(this); } save(completeName){ var names = this.state.names.concat(completeName); this.setState({ names: names, name: "" }); } echo(incompleteName){ this.setState({name: incompleteName}); } render(){ return( <div> <GreetingList names={this.state.names} /> <Echo name={this.state.name} onChange={this.echo} onSave={this.save}/> </div> ); } } var names = ["Murayama", "Takahashi", "Sanada"]; ReactDOM.render( <Welcome names={names} />, document.getElementById('example') ); </script> </body> </html>
Reactだけ学ぶハンズオン 4/5
Part4 Echo - ハンズオン
ここでは入力した内容を表示するReactアプリケーションを作成します。
開発は以下の手順で進めます。
1. ライブラリの設定
titleタグ以外は前章と同じです。ファイル名は04_echo.htmlという名前で保存しておきます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 04</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> </script> </body> </html>
2. コンポーネント仕様を定義
ここでは画面の入力を受け付けるテキストボックスと、入力された名前を表示する領域を持ったとEchoコンポーネントクラスを作成します。
Echoコンポーネントの仕様は以下のとおりです。
class Echo extends React.Component { constructor(props) { super(props); this.state = {name: ""}; // bind this this.echo = this.echo.bind(this); } echo(e){ this.setState({name: e.target.value}); } render() { return ( <div> <h1>Welcome to WEBZ.</h1> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} /> <h3>{this.state.name}</h3> </div> ); } }
renderメソッド以外にconstructor、echoメソッドの2つが追加されています。constructorの説明に入る前にReactのステートについて学習しておきましょう。
Reactにはステートという仕組みがあります。ステートとはコンポーネントの状態を表すものです。上記のEchoコンポーネントには「(入力された)名前」を示すnameというステートがあります。Reactのコンポーネントはステートの内容が更新されると自動的に再描画(renderメソッド呼び出し)されるようになっています。
constructorはReactコンポーネントのライフサイクルメソッドの1つで、コンポーネントインスタンスの生成時に呼び出されます。constructorでステートの初期値を設定できます。
constructor(props) { super(props); this.state = {name: ""}; // bind this this.echo = this.echo.bind(this); }
上記のコードではnameステートの初期値を空文字で設定しています。
this.echo = this.echo.bind(this); は後の echoメソッド を利用できるようにしています。
つづいてechoメソッドを見てみましょう。
echo(e){ this.setState({name: e.target.value}); }
echoメソッドはReactの仕組みに依存したものではなく、アプリケーション独自のメソッドです。echoメソッドはrenderメソッドの中でinputタグのonChangeイベントハンドラに関連付けられています。
<input type="text" onChange={this.echo} />
これによって、テキストボックスの値に変化が生じるとechoメソッドが呼び出されるようになります。echoメソッドの中では、コンポーネントのステートを更新するためにsetStateメソッドを呼び出しています。Reactは内部で仮想DOMによってコンポーネントを管理しているため、ステートを更新する場合、必ずsetStateメソッドを使用する必要があります。*1
echoメソッドによってステートが更新されるとコンポーネントのrenderメソッドがReactによって呼び出されます。
render() { return ( <div> <h1>Welcome to WEBZ.</h1> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} /> <h3>{this.state.name}</h3> </div> ); }
これによってテキストボックスに入力した内容が即座に画面に表示されるようになります。
3. コンポーネントクラスをレンダリング
作成したコンポーネントクラス(Echo)を画面にレンダリングします。
ReactDOM.render( <Echo />, document.getElementById('example') );
Echoコンポーネントにプロパティの指定はありません。
ここまでの作業をまとめると次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 04</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> class Echo extends React.Component { constructor(props) { super(props); this.state = {name: ""}; // bind this this.echo = this.echo.bind(this); } echo(e){ this.setState({name: e.target.value}); } render() { return ( <div> <h1>Welcome to WEBZ.</h1> <h3>Please type your name.</h3> <input type="text" onChange={this.echo} /> <h3>{this.state.name}</h3> </div> ); } } ReactDOM.render( <Echo />, document.getElementById('example') ); </script> </body> </html>
Reactだけ学ぶハンズオン 3/5
Part3 GreetingList - ハンズオン
ここでは次のようなメッセージ一覧を表示するReactアプリケーションを作成します。
開発は以下の手順で進めます。
1. ライブラリの設定
titleタグ以外は前章と同じです。ファイル名は03_greeting_list.htmlという名前で保存しておきます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 03</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> </script> </body> </html>
2. コンポーネント仕様を定義
Reactのコンポーネントクラスを定義するために、コンポーネント仕様を作成します。*1ここではHelloと挨拶するGreetingItemクラスと、複数のGreetingItemを管理するGreetingListクラスを定義します。
GreetingItemクラスは以下のとおりです。
class GreetingItem extends React.Component { render() { return ( <li>Hello {this.props.name}</li> ); } }
前章で作成したGreetingクラスとほとんど同じです。nameプロパティの内容をレンダリングします。
続いてGreetingListクラスです。
class GreetingList extends React.Component { render() { var greetingItems = this.props.names.map(function(name, i){ return <GreetingItem name={name} key={i} />; }); return ( <div> <h1>Welcome to Webz</h1> <ul>{greetingItems}</ul> </div> ); } }
GreetingListコンポーネントはnamesプロパティから名前の配列を受け取ります。実際の値の受け渡しは後のrenderフェーズで指定します。
renderメソッドではnamesプロパティをループして、JSXを使ってGreetingItem要素を定義しています。Reactは仮想DOMを使って要素を管理しているので、各要素にはkey属性を指定して一意な値を定義する必要があります。
3. コンポーネントクラスをレンダリング
作成したコンポーネントクラス(GreetingList)を画面にレンダリングします。GreetingListコンポーネントにnamesプロパティを指定している点を確認しておいてください。
var names = ["Murayama", "Takahashi", "Sanada"]; ReactDOM.render( <GreetingList names={names} />, document.getElementById('example') );
ここまでの作業をまとめると次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 03</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> class GreetingItem extends React.Component { render() { return ( <li>Hello {this.props.name}</li> ); } } class GreetingList extends React.Component { render() { var greetingItems = this.props.names.map(function(name, i){ return <GreetingItem name={name} key={i} />; }); return ( <div> <h1>Welcome to Webz</h1> <ul>{greetingItems}</ul> </div> ); } } var names = ["Murayama", "Takahashi", "Sanada"]; ReactDOM.render( <GreetingList names={names} />, document.getElementById('example') ); </script> </body> </html>
Reactだけ学ぶハンズオン 2/5
Part2 Greeting - ハンズオン
ここでは次のようなメッセージを表示するReactアプリケーションを作成します。*1
開発は以下の手順で進めます。
1. ライブラリの設定
titleタグ以外は前章と同じです。ファイル名は02_greeting.htmlという名前で保存しておきます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 02</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> </script> </body> </html>
2. コンポーネント仕様を定義
Reactのコンポーネントクラスを定義するために、コンポーネント仕様を作成します。
class Greeting extends React.Component { render() { return ( <div> <h1>Welcome to Webz</h1> <h2>Hello {this.props.name}</h2> </div> ); } }
renderメソッドではJSXを使ってコンポーネントを定義していますが、h2タグの中で{this.props.name}を指定しています。これはReactのプロパティという仕組みを使っています。プロパティとはReactコンポーネントの外部インタフェースです。ここでは外部から指定されたnameプロパティを表示するようにしています。nameプロパティの指定は、後のレンダリング時に指定します。
3. コンポーネントクラスをレンダリング
作成したコンポーネントクラス(Greeting)を画面にレンダリングします。前章とほとんど同じですが、Greetingコンポーネントにnameプロパティを指定している点を確認しておいてください。
var name = "Murayama"; ReactDOM.render( <Greeting name={name} />, document.getElementById('example') );
ここまでの作業をまとめると次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 02</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> class Greeting extends React.Component { render() { return ( <div> <h1>Welcome to Webz</h1> <h2>Hello {this.props.name}</h2> </div> ); } } var name = "Murayama"; ReactDOM.render( <Greeting name={name} />, document.getElementById('example') ); </script> </body> </html>
*1:Webzてのは勉強会(コミュニティ)の名前です。気にせずに。。
Reactだけ学ぶハンズオン 1/5
Reactとは
ReactはUIをつくるためのJavaScriptライブラリです。
- Declarative
- 宣言的なプログラミング(たとえばExcelのsum関数みたいな仕組み)
- Component-Based
- コンポーネントベース(画面を構成する部品を作っていく)
- Learn Once, Write Anywhere
- 一度学べば、どこでも動く(詳しくはRact Native)
Part1 Hello React - ハンズオン
ここでは次のような画面にHello Worldと表示するReactアプリケーションを作成します。
開発は以下の手順で進めます。
1. ライブラリの設定
Reactで配布されてるreact.js、react-dom.jsを使用します。
<script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script>
また、JSXをサポートするためにBabelを使用します。
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script>
ここまでの作業をまとめると以下のとおりです。ファイル名は01_hello.htmlという名前で保存しておきます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 01</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> </body> </html>
2. コンポーネント仕様を定義
これからJavaScriptをゴリゴリ記述していくので、HTMLファイルのbodyタグの中にdivタグとscriptタグを定義します。scriptタグのtype属性にはtext/babelを指定してください。これでJSXシンタックスが利用できます。
<body> <div id="example"></div> <script type="text/babel"> </script> </body>
divタグはこれから作成するコンポーネントのコンテナとなる要素です。
ここでは画面にHello Worldと出力するコンポーネント仕様を定義し、コンポーネントクラスHelloWorldを作成します。ReactはコンポーネントをJSXで定義可能です。
scriptタグの中に以下のコードを記述します。
class HelloWorld extends React.Component { render() { return <h1>Hello World</h1>; } }
ここではes6(ES2015)のオブジェクト指向構文から導入されたclass命令を使ってクラスを定義しています。ここで定義したHelloWorldクラスはReact.Componentを継承しています。このようなクラスはReactコンポーネントと呼ばれます。Reactコンポーネントには必ずrenderメソッドを定義しなくてはいけません。
コンポーネントとは部品という意味です。
renderメソッドの内部では、戻り値がHTMLのようになっています。このような表記法はJSXと呼ばれ、コンポーネントを手軽に記述することができます。JSXをサポートするにはbabelライブラリを読み込む必要があります。JSXの利用は任意です。
3. コンポーネントクラスをレンダリング
作成したコンポーネントクラスを画面にレンダリングします。ReactDOM.renderメソッドの引数にコンポーネントクラス、コンポーネントのコンテナとなるDOM要素を指定します。
ReactDOM.render(<HelloWorld />, document.getElementById('example'));
ここまでの作業をまとめると次のようになります。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello React 01</title> <script src="https://unpkg.com/react@15.6.1/dist/react.js" charset="utf-8"></script> <script src="https://unpkg.com/react-dom@15.6.1/dist/react-dom.js" charset="utf-8"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> class HelloWorld extends React.Component { render() { return <h1>Hello World</h1>; } } ReactDOM.render(<HelloWorld />, document.getElementById('example')); </script> </body> </html>