JSひろばアプリ開発3日目:Vueアプリの全体像

JSひろばアプリ作成まで~3日目

前回の記事では、Piniaを入れて大まかなレイアウトを作成しました。 今回はPiniaやemit()、テンプレートrefを使うのでVueの要素が盛りだくさんです。 今日で大まかなフロントエンドの部分を完了させます! 作業日 2022年12月12日 作業にかけた時間 3時間 合計作業時間 9時間 作業内容 ボタンのコンポーネントの作成モックのデータを作成グローバルで使うデータをPiniaに保管させるEmitを使いデータを親コンポーネントに送るライブラリコンポーネントのRefにアクセスする 3つのファインダーコンポーネント では、このJSひろばのアプリのメイン機能としてこの4つのファインダーがありましたがおすすめ検索機能はキーワード検索とほぼ同じなのでいったん取り除くことにしました。 これは、ユーザーがJavaScriptのサンプルコードを見つけるための機能になります。 ボタンのコンポーネント 各ボタンを押すとそれぞれのボタンに付属した内容が同じダイアログ(ポップアップ)のコンポーネント内で表示されるようにします。 まずは、各4種類の検索機能のコンポーネントをcomponents/finderフォルダに作成します。最初の中身はただのテキストでOKです。次にApp.vueに戻りPrimeVueにあるDialogコンポーネントをコピペします。 それから、各ボタンを押したときにそれぞれのコンポーネントの内容が表示されるようにロジックを作成すればOKです。 途中経過ですが、こんな感じになりました。 実際の画面はこんな感じです。 キーワード検索 まだ、データベースの細かい構成とデータの量を吟味していないので詳しくはすすめられません。ここで検討すべき課題はこちらになります。 このファインダー機能のコンポーネントは複雑になるので作成はいったん後回しにします。 Piniaの作成 Piniaを使ってグローバルにアクセスできるストレージを作成します。とりあえず、モックのJSONファイルを作成してテーブルとして表示できるところまでやってみます。 これを各テーブルで表示させるとこんな感じになりました。 履歴のデータを保管する 各コマンドを実行した後に、その履歴をオブジェクトの配列に保管します。常に最新の履歴が先に来るようにしたいため、pop()ではなく、unshift()を使っています。 コンソール関係のコードはこのような感じです。 これで入力したコマンドがオブジェクトとして配列に保管されました。テーブルにも問題なく表示されていることが分かります。 コードをコンソールにコピーする機能 では、検索機能で探したコマンドをコンソールにコピーするボタンのファンクションを作成していきます。ドキュメンテーションにはないですがこのターミナルがどうやって入力されたテキストをバインドしているか見てみましょう。 VueのGoogleエクステンションツールを使います。 VueのタブからTerminalのコンポーネントを開きます。すると、DataのところにcommandTextがあるのがわかります。ここがnullになっていますがターミナルにテキストが入力されると同時に更新されました。 では、このデータにコピーしたいコピーをバインドさせるようにします。 まず、ここのcommandTextにアクセスするには<Terminal ref=”terminal”/>のようにrefを使ってこのコンポーネント内にあるデータ、関数にアクセスすることができますね。(Compostion APIの場合は対象のコンポーネント側でexpose()されて公開されている必要がありますが。) あとは、テーブル側のボタンにemit()を設定して親コンポーネントにコマンドのデータを送ってあげます。 親コンポーネント側では、Emitを受け取ったときに発火するイベントを下記の様に設定してあげました。 細かいスタイルの変更 ここまでできたら、大体のレイアウトは決まったのでスタイルをキレイにしていきます。 特に、モバイルとデスクトップで共通のアプリを使えるようにしたいのでその設定も必要です。 とりあえずこんな感じになりました。ポップアップで表示されるダイアログは実際のデータが入ってからスタイリングをしたいと思います。 では、フロントエンドはこれくらいにして次回からにバックエンドにかかりましょう。 お疲れ様です。

JSひろばアプリ開発2日目:スタイルの設定

JSひろばアプリ作成まで~2日目

前回の記事ではアプリの概要とデザインを全体像として決めました。 今日は、もう少し具体的なフロントエンドのデザインを設計していきます。ファイル構成(どの段階でコンポーネントにするか)とPrimeVueのライブラリを見ながらサクサク進めていきたいです。 ちなみにバックエンドも同時に進めても良かったのですが、割と簡単な作業になりそうなので、モックのJSONファイルで先にフロントエンドでテストをしてからでも良いと判断しました。ですので先にVueのアプリケーションから固めていきます。 作業日 2022年12月10日 作業にかけた時間 3時間 合計作業時間 6時間 作業内容 Figmaのデザインを形にしていくファイル構成を考えるVueコンポーネントの作成Piniaのインストール PrimeFlexのインストール 前回入れていなかったので、今回使うCSSライブラリのPrimeVueで使うCSSユーティリティをインストールします。 これでクラスを使ってマージンの設定やFlexの設定ができるようになりました。 次にGoogleフォントを追加しました。CDNでfontをリンクさせました、必要に応じてフォントのファイルをダウンロードしてローカルから使うようにすることも考えています。 main.jsに下記のimport ‘@/assets/global.css’をインポートしました。 スタイルはできるだけPrimeVueのものを使い、カスタムしたい場合は.Vueファイルの下に<style></style>を作成してそこにCSSを書きました。 ざっくりと全体像を作成しました。 ユーザーエクスペリエンスの向上のために下記のことを先に達成したいです。 これを実現するにはいくつか方法がありますが、PrimeVueのコンポーネントでダイナミックダイアログというものがあったのでこれで対応していきます。 さらに上記でごちゃごちゃした検索機能とか、ボタンの枠を固定してボタンを押すとこのダイアログが表示されるようにします。なのでこれらはコンポーネントにまとめてあげましょう。 とりあえずポップアップが開くところまではOKですね。 Piniaのインストール 次にPiniaをインストールします。単純にreactive()でオブジェクトとしてデータまとめても良いのですが、propsでごちゃごちゃしていくと後からの修正が大変なので、グロバールでアクセスできるPiniaの方がよいと判断しました。 Piniaの使い方はこちらで説明しています。 ではPiniaのインストールが完了したらmain.jsに追加します。 その後にstore.jsというファイル名でアプリに使うデータをPiniaを使ってここに保管させます。 どのようなデータを保管するか具体的な構成は次回までに考えておきます。 とりあえずこんな感じでPiniaで作成したStoreデータをメインの画面に表示させることができました。 Piniaのファイルはこのように書きました。 App.VueのファイルにはこのようにPiniaをインポートしました。 では、次回にポップアップの中身と検索機能を作成していきたいと思います。 お疲れ様です。

JSひろばアプリ開発1日目:プロジェクトのセットアップ

JSひろばアプリ作成まで~1日目

私がプログラミングを独学で始めたのた2020年の3月、ニューヨークでコロナがちょうど発生した時でした。 それから片手間にPythonを1年くらい学び、その後にJavaScriptを後に学び始めました。 それからチケット管理アプリをデモで作りましたが、もっと実践で使えそうなアプリを作りたいと思い、今回のJSひろばアプリを作ることに決めました。 今回はプログラミングを始めたい人の為にすべての作業をゼロから行い、コードもすべてオープンソースで公開いたします。 作業の内容 作業日 2022年12月8日 作業にかけた時間 3時間 合計作業時間 3時間 作業内容 アイディアを絞るUIをFigmaでデザインする使用するテクノロジーを決める課題点をクリアする JSひろば JSひろばという名前でアプリを進めていきます。これは、ユーザーがJSエンジンのコンソールにウェブページからインプットできて、ファンクションやWindowオブジェクトの仕組みを実際に試しながら学ぶアプリです。 下記がアプリのイメージになります。 これは無料デザインツールのFigmaを使って作りました。詳しいFigmaの使い方はこの記事で紹介しています。 当初はユーザー登録をしてユーザーが好きなコードの投稿や、お気に入りのコードを登録する機能までつけてみようかと思いましたが、機能の実装までにかなり時間がかかりそうなのでとりあえずはなしで進めます。 今回のスタック JSひろばアプリは今まで使ってきたPtyhonのウェブフレームワークのDjangoとそれをREST APIにしてくれるライブラリを使います。 フロントエンドはReactを使おうかなと思ったけどVueの方が慣れているのでそちらを使います。 Djangoだとついてくるアドミンパネルからデータのエントリーができるのでこれもプラスですね。 では、今回のスタックDjango+PostgreSQL+Vueのイメージ図です。 eval()の脅威 今回、ユーザーがウェブページからeval()のメソッドを使ってコンソールと同じようにリスポンスを返すようにしたいのが一番の目的でした。しかしeval()はセキュリティ上使わない方がよいようですね。 有名なハッキング手法のうちの一つにEVAL インジェクション(eval injection)があることを知りました。 これは、JavaScriptのデーターフォーマットをであるJSON (JavaScript Object Notation)に不正なコードを挿入し想定外の動作を誘導する攻撃手法です。特にPHPをサーバーで使っている場合は危険のようですね。 今回は下記の点からeval()を使っても良いと判断しました。 Vueのプロジェクト作成 Vueのスタックはこんな感じです。 Vue + PrimeVue(UIライブラリ)+ Vite + Pinia 今回はさくさくに動くViteのビルドツールを使います。 とりあずJavaScriptでコンソールをウェブページに実装できるところまで進めます。 UIで使うCSSライブラリはPrimeVueにします。詳しいライブラリの説明はこちらで見てください。 TailwindCSSでもよかったのですが、PrimeVueに使えそうなターミナルのコンポーネントを発見しました! まさにこれをアプリのメインのターミナルとして使いたいですね。 ではPrimeVueもインストールしましょう。詳しいPrimeVueの設定の仕方はこちらを参照してください。 とりあえずここまでできました。 ではPrimeVueのコンポーネントを使ってキレイにしましょう。 細かいインプットの制限やコードの整理はまた次回に行います。 GitHubでコードを公開しているので見てください。 GitとGitHubの使い方もYouTubeで説明しているのでよかったらどうぞ。 完成したアプリはこちらからどうぞ。

ReactをUbuntuサーバーからデプロイする(Nginx)

React デプロイの仕方

今日はUbuntuサーバーからReactアプリのデプロイをする方法を紹介していきます。 Vueのアプリをデプロイする方法はこちらからどうぞ! 今日はnpx create-react-appの代わりにViteを使ってReactアプリをビルドしていきます。 なぜReactをViteでセットアップすべきなのかを知りたい方はこちらからどうぞ! どちらを使うにしてもビルドのコマンド(Viteならnpm run build)でJavaScriptのコード、画像ファイル、スタイル、HTMLファイルをdistディレクトリにまとめられます。 今回はUbuntuとウェブサーバーのNginxを使ってReactアプリをデプロイします。 では早速本題にとりかかりましょう。 準備しておくこと Reactのアプリを準備する ではローカルの環境でサーバーにアップロードするためのReactのファイルを作成しましょう。 すでにReactのアプリが準備できている場合はこの手順を飛ばしてください。 npm run devでテストサーバーからReactのアプリがブラウザで見ることができれば一旦OKです。 UbuntuサーバーにSSHで接続 ではサーバーに遠隔で入るためにSSHを使いましょう。 私のおすすめはフリーソフトのMobaXtermです。 こちらの記事で詳しいMobaXtermの使い方を説明しているので参考にしてください。 ではサーバーのIP、ポート22(通常は)、ユーザーIDとパスワードを使ってサーバーに接続しましょう。 ではrootで接続していた場合はUbutuのユーザーに切り替えます。 Reactのファイルをアップロードする では適当な場所にReactのアプリケーションを上げます。指定がない場合はUbutnuのユーザーのフォルダにアップロードしましょう。 MobaXtermのクライアントだとSSHで接続された状態で、ファイルの転送がドラッグ&ドロップで実現できます。 ここに新しく「React-Tutorials」という名前を付けてReactのファイルをアップロードします。ディレクトリ名は皆さんのアプリに適したものにしましょう。 ここで、GitHubにあるリポジトリからクローンすることもできるのでそちらの方が実用的かもしれません。GitとGitHubの使い方はこの動画を参考にしてください。 Nginxのコンフィグファイルを作成 ではNginxをインストールする記事を読んで先に下準備を済ませておきます。 ではこのNginxのコンフィグファイルに下記の様に書いていきます。 私の場合はこのようになりました。 ではCtl+OもしいくはCtl+Xでデータを上書きしてnanoのテキストエディタを閉じます。 次にsites-availableからsite-enabledにシンボリックリンクを作成します。このsites-enabledにあるファイルをNiginxが読み取りサイトを公開するようになっていますので。 ではsites-enabledの方にもファイルができていたらOKですね。 ポートを開放する 先ほどのNignxのファイルでポート80番を開けていた場合はデフォルトで空いていると思いますがもし、私の例の場合のようにポート83番からデプロイしたい場合はファイヤーオールの設定で許可する必要があります。今後、一つのサーバーから複数のアプリケーションをデプロイする方法も紹介しているのでよかったら試してみてください。 あとNginxのサービスをリスタートすることを忘れずに デプロイしたサイトにアクセス では実際にデプロイしたReactアプリケーションにアクセスしてみましょう。 http://172.104.81.40:83/ おめでとうございます。 もしうまくいかない場合は、コメントに詳しい状況を書いてくださいね。 お疲れ様でした。

ReactをViteとTailwindでセットアップする

React Vite Tailwindcss

今までcreate-react-appでReactのプロジェクトを使ってきて遅いなと感じた方、是非このコンビネーションを試してください。今日はReactでセットアップしますがVueでも同じことができるので試してください。 ReactとViteだけのセットアップの仕方はこちらでも紹介しています。 React + TailwindCSS + Vite で夢のような最速サイトが実現できます。 Viteとは ViteはVueの創生者Evan Youとそのチームが作った最新のビルドツールです。特徴としてはWebpack、Gulp、Parcelのバンドリングで使うパッケージがデベロップメント用のサーバーを起動する際(npm start)でかなり遅くなる原因を起こしていたものをすべて取り除きました。さらにコードの量が多くなるにつれ再度バンドルしなおすのでその分時間がかかっていました。 Viteの強みはその速さになります。もちろん、その引き換えにES6で書いたコードが対応していないブラウザではJavaScriptを変換してくれないので動かない可能性がある等の短所があります。 ViteでVueのプロジェクトをビルドする方法はこちらからどうぞ。 では下記のコマンドでViteを使ってReactのプロジェクトを作成します。 TailwindCSSをインストールする では下記のコマンドからTailwindCSSをインストールします。 このinitでイニシャライゼーションが終わるとコンフィグファイルが作成されたというメッセージが表示されます。 では、tailwind.config.cjsファイルを見てみましょう。 では、下記の様にすべてのテンプレートファイルがここに含まれるようにします。 次にsrcディレクトリのindex.cssファイルに下記の行を追加しましょう。 ここで使っているVSCode若しくはお使いのテキストエディタにエラーが出た場合はpostcssのエクステンションを入れてください。 TailwindCLIでCSSをビルドさせる postcssを使用しない場合は下記の方法でTailwindCSSをビルドさせましょう。 では下記のコマンドで実際にdistribution(公開)をするためにテンプレートをCSSをスキャンさせます。 これで、Tailwindが実際に使用したCSSだけのファイルを作成してくれるので軽量なファイルに仕上がります。素晴らしいですね。 Tailwindが使えるようになった ではこれでTailwindのclassをReactのclassNameで使用してCSSがつかるようになったことを確認しましょう。 ではブラウザの検証モードで対象のHTML要素を見てみます。 できました! 実際のコードはGitHubから公開しているので見てください。 ではお疲れ様でした。

React講座 state のリフトアップ

react state

しばしば、いくつかのコンポーネントが同一の変化するデータを反映する必要がある場合があります。そんなときは最も近い共通の祖先コンポーネントへ共有されている state をリフトアップすることを推奨します。これを、実際にはどのように行うかを見てみましょう。 この章では、与えられた温度で水が沸騰するかどうかを計算する温度計算ソフトを作成します。 BoilingVerdict というコンポーネントから始めましょう。これは温度を celsius という props として受け取り、水が沸騰するのに十分な温度かどうかを表示します。 次に Calculator と呼ばれるコンポーネントを作成します。温度を入力するための <input> 要素をレンダーし、入力された値を this.state.temperature に保持します。 加えて、現在の入力値を判定する BoilingVerdict もレンダーします。 2 つ目の入力を追加する 新しい要件は、摂氏の入力に加えて、華氏の入力もできるようにして、それらを同期させておくことです。 Calculator から TemperatureInput コンポーネントを抽出するところから始めましょう。props として、”c” もしくは “f” の値をとる scale を新しく追加します: これで Calculator を 2 つの別個の温度入力フィールドをレンダーするように変更することができます: 2 つの入力フィールドが用意できました。しかし、片方に温度を入力しても、もう片方は更新されません。これは要件を満たしていません: 2 つの入力フィールドを同期させたいのです。 Calculator から BoilingVerdict を表示することもできません。Calculator は TemperatureInput の中に隠されている現在の温度を知らないのです。 変換関数の作成 まず、摂氏から華氏に変換するものとその反対のものと、2 つの関数を書きます。 これら 2 つの関数は数字を変換します。次に文字列で表現された temperature と変換関数を引数に取り文字列を返す、別の関数を作成します。この関数を一方の入力の値をもう一方の入力に基づいて計算するのに使用します。 常に値が小数第 3 位までで四捨五入されるようにし、無効な temperature には空の文字列を返します。 例えば、tryConvert(‘abc’, toCelsius) は空の文字列を返し、tryConvert(‘10.22’, toFahrenheit) は ‘50.396’ を返します。 state のリフトアップ 現時点では、両方の TemperatureInput コンポーネントは独立してローカルの state を保持しています: しかし、2 つの入力フィールドはお互いに同期されていて欲しいのです。摂氏の入力フィールドを更新したら、華氏の入力フィールドも華氏に変換された温度で反映されて欲しいですし、逆も同じです。 React での state の共有は、state を、それを必要とするコンポーネントすべての直近の共通祖先コンポーネントに移動することによって実現します。これを “state のリフトアップ (lifting state up)” と呼びます。TemperatureInput からローカルの state を削除して Calculator に移動しましょう。 Calculator が共有の … Read more

react講座 リストと key

react list and key

Reactでリストを作成する前に、JavaScript でリストを変換する方法についておさらいしましょう。 以下のコードでは、map() 関数を用い、numbers という配列を受け取って中身の値を 2 倍にしています。map() 関数が返す新しい配列を変数 doubled に格納し、ログに出力します: このコードはコンソールに [2, 4, 6, 8, 10] と出力します。 React で配列を要素のリストに変換する方法は上記に似ています。 複数のコンポーネントをレンダーする 要素の集合を作成し中括弧 {} で囲むことで JSX に含めることができます。 以下では、JavaScript の map() 関数を利用して、numbers という配列に対して反復処理を行っています。それぞれの整数に対して <li> 要素を返しています。最後に、結果として得られる要素の配列を listItems に格納しています: そして、listItems という配列全体を <ul> 要素の内側に含めます: このコードは、1 から 5 までの数字の箇条書きのリストを表示します。 基本的なリストコンポーネント 通常、リストは何らかのコンポーネントの内部でレンダーすることをが実用的です。 前の例をリファクタリングして、numbers という配列を受け取って要素のリストを出力するコンポーネントを作ることができます。 このコードを実行すると、「リスト項目には key を与えるべきだ」という警告が表示されます。“key” とは特別な文字列の属性であり、要素のリストを作成する際に含めておく必要があるものです。なぜ key が重要なのかは後に説明します。 numbers.map() 内のリスト項目に key を割り当てて、key が見つからないという問題を修正しましょう。 Key Key は、どの要素が変更、追加もしくは削除されたのかを React が識別するのに必要になります。配列内の項目に安定した識別性を与えるため、それぞれの項目に key を与えるべきです。 Keyはリレーショナルデータベースでいうプライマリーキーと同じイメージになります。いわば、ユニークなIDのことです。これで同じデータ(例:”田中さん”、”田中さん”)が複数あってもどのデータを指しているのかを判断できるようになりますね。 データ間でその項目を一意に特定できるような文字列を key として選ぶのが最良の方法です。多くの場合、のデータ内にある ID を key として使うことになるでしょう: レンダーされる要素に安定した ID がない場合、最終手段として項目のインデックス(順番)を使うことができます: 要素の並び順が変更される可能性がある場合、インデックスを key として使用することはお勧めしません。パフォーマンスに悪い影響を与え、コンポーネントの状態に問題を起こす可能性があるからです。もし明示的に key … Read more

react講座 条件付きレンダー

react 条件付きレンダー

React ではロジックをカプセル化した独立したコンポーネントを作ることができます。そして、あなたのアプリケーションの状態に応じて、その一部だけを更新、表示することが可能です。 React における条件付きレンダーは JavaScript における条件分岐と同じように動作します。if もしくは条件演算子のような JavaScript 演算子を使用して現在の状態を表す要素を作成すれば、React はそれに一致するように UI を更新します。 以下の 2 つのコンポーネントを見てみましょう。 ユーザがログインしているかどうかによって、これらのコンポーネントの一方だけを表示する Greeting コンポーネントを作成しましょう: この例では isLoggedIn プロパティの値によって異なる挨拶メッセージを表示します。 要素変数 要素を保持しておくために変数を使うことができます。これは、出力の他の部分を変えずにコンポーネントの一部を条件付きでレンダーしたい時に役立ちます。 ログアウトとログインボタンを表す以下の 2 つの新しいコンポーネントを考えましょう: 以下の例では、LoginControl というステート付きコンポーネントを作成します。 LoginControl は現在の state によって <LoginButton /> もしくは <LogoutButton /> の一方をレンダーします。加えて、前の例の <Greeting /> もレンダーします: Try it on CodePen 変数を宣言して if 文を使用することはコンポーネントを条件的にレンダーするなかなか良い方法ではありますが、より短い構文を使いたくなる時もあります。以下で述べるように、JSX でインラインで条件を記述する方法がいくつか存在します。 論理 && 演算子によるインライン If 中括弧で囲むことで、JSX に式を埋め込むことができます。これには JavaScript の論理 && 演算子も含まれます。これは条件に応じて要素を含めたいというときに便利です。 Try it on CodePen これが動作するのは、JavaScript では true && expression は必ず expression と評価され、false && expression は必ず false と評価されるからです。 従って、条件部分が true であれば、&& の後に書かれた要素が出力に現れます。もし false であれば、React はそれを無視して飛ばします。 falsy … Read more

React講座 イベント処理

react イベント処理

React でのイベント処理は DOM 要素のイベントの処理と似ています。まずは、いくつかの文法的な違いがあるので見ておきましょう。 例として、以下の HTMLを見てください。 は、React では少し異なります: 別の違いとして、React では false を返してもデフォルトの動作を抑止することができません。明示的に preventDefault を呼び出す必要があります。例えば、プレーンな HTML では、「フォームをサブミットする」という form 要素のデフォルト動作を抑止するために次のように書くことができます。 React では、代わりに次のようになります: ここで、e は合成 (synthetic) イベントです。React はこれらの合成イベントを W3C の仕様に則って定義しているので、ブラウザ間の互換性を心配する必要はありません。React のイベントはネイティブのイベントと全く同様に動作するわけではありません。 React を使う場合、一般的には DOM 要素の生成後に addEventListener を呼び出してリスナを追加する必要はありません。代わりに、要素が最初にレンダーされる際にリスナを指定するようにしてください。 コンポーネントを ES6 のクラスを使用して定義した場合、一般的なパターンではイベントハンドラはクラスのメソッドになります。例えば、以下の Toggle コンポーネントはユーザが “ON” 状態 “OFF” 状態を切り替えられるようなボタンをレンダーします。 JSX のコールバックにおける this の意味に注意しなければなりません。JavaScript では、クラスのメソッドはデフォルトではバインドされません。this.handleClick へのバインドを忘れて onClick に渡した場合、実際に関数が呼ばれた時に this は undefined となってしまいます。 これは React に限った動作ではなく、JavaScript における関数の仕組みの一部です。一般的に、onClick={this.handleClick} のように () を末尾に付けずに何らかのメソッドを参照する場合、そのメソッドはバインドしておく必要があります。 bind の呼び出しが苦痛である場合、それを回避する方法が 2 つあります。パブリッククラスフィールド構文を使えば、コールバックを正しくバインドすることができます: この構文は、Create React App ではデフォルトで有効です。 クラスフィールド構文を使用しない場合、コールバック内でアロー関数を使用することもできます: この構文での問題は、LoggingButton がレンダーされるたびに異なるコールバック関数が毎回作成されるということです。大抵のケースではこれは問題ありません。しかし、このコールバックが props の一部として下層のコンポーネントに渡される場合、それら下層コンポーネントが余分に再描画されることになります。 一般的にはコンストラクタでバインドするかクラスフィールド構文を使用して、この種のパフォーマンスの問題を避けるようおすすめします。 イベントハンドラに引数を渡す ループ内では、イベントハンドラに追加のパラメータを渡したくなることがよくあります。例えば、id という行の ID がある場合、以下のどちらでも動作します: 上記の … Read more

react講座 state とライフサイクル

React ライフサイクル

この章では React コンポーネントにおける state(状態) とライフサイクルについての導入を行います。 以前の章のひとつにあった秒刻みの時計の例を考えてみましょう。要素のレンダーの章にて、UI を更新するための方法をひとつだけ学びましたね。それはレンダーされた出力を更新するために root.render() を呼び出す、というものでした。 このセクションでは、この Clock コンポーネントを実用的に再利用可能かつカプセル化されたものにする方法を学びます。コンポーネントが自身でタイマーをセットアップし、自身を毎秒更新するようにします。 では時計の見た目をカプセル化するところから始めてみましょう: しかし上記のコードは重要な要件を満たしていません:Clock がタイマーを設定して UI を毎秒ごとに更新するという処理は、Clock の関数内で実現されるべきだということです。 理想的には以下のコードを一度だけ記述して、Clock に自身を更新させたいのです: これを実装するには、Clock コンポーネントに “ステート (state)” を追加する必要があります。 state は props に似ていますが、コンポーネントによって完全に管理されるプライベートなものです。 stateは状態管理の倉庫とイメージしてください。例えば気温のデータや不動産の値段など、ユーザーが入力したり、データを参照できるようなものです。 関数をクラスに変換する 以下の 5 ステップで、Clock のような関数コンポーネントをクラスに変換することができます。 これで、Clock は関数ではなくクラスとして定義されるようになりました。 render メソッドは更新が発生した際に毎回呼ばれますが、同一の DOM ノード内で <Clock /> をレンダーしている限り、Clock クラスのインスタンスは 1 つだけ使われます。このことにより、ローカル state やライフサイクルメソッドといった追加の機能が利用できるようになります。 クラスにローカルな state を追加する 以下の 3 ステップで date を props から state に移します: 親クラスのコンストラクタへの props の渡し方に注目してください: クラスのコンポーネントは常に props を引数として親クラスのコンストラクタを呼び出す必要があります。 タイマーのコードはコンポーネント自身に後で追加しなおします。 結果は以下のようになります: 次に、Clock が自分でタイマーを設定し、毎秒ごとに自分を更新するようにします。 クラスにライフサイクルメソッドを追加する 多くのコンポーネントを有するアプリケーションでは、コンポーネントが破棄された場合にそのコンポーネントが占有していたリソースを解放することがとても重要です。つまりは使わなくなったコンポーネントを外すという事になります。 タイマーを設定したいのは、最初に Clock が DOM として使用されるときです。このことを … Read more