前回の記事ではReactの応用として、
- if/else文について
- JSX内で使用しやすくするため、三項演算子が好まれて使われていること
を中心に学びました。
今回は、
コンポーネントの状態に基づいてインライン CSS を条件付きで変更する
if/else文を使用したレンダーとインラインスタイルでのCSSの使用を学びました。
このセクションでは、Reactコンポーネントの状態によって条件分岐を用いてCSSをレンダーすることを学びました。
つまり、条件に基づいて、条件が満たされている場合は、renderメソッドなのJSX要素に割り当てられているスタイルオブジェクトを適用します。
この方法は、DOM 要素を直接変更してスタイルを適用するという従来のアプローチと比べて、かなり大きな変更となるため、理解することが重要です (たとえば jQuery ではごく一般的です)。 このアプローチでは、要素がいつ変更されたのかを追跡する必要があり、実際の操作を直接処理する必要もあります。 変更の追跡が困難になり、UI が予測できなくなる可能性があります。 条件に基づいてスタイルオブジェクトを設定するときは、UI をアプリケーションの状態の関数としてどのように表示するかを記述します。 情報の流れは明確で、一方向にしか流れません。 React でアプリケーションを記述するときは、こうした方法が適切です。
https://www.freecodecamp.org/japanese/learn/front-end-development-libraries/react/change-inline-css-conditionally-based-on-component-state
課題として下記のようなものがありました。
コードエディターに、スタイル付きの境界線を持つ、シンプルな制御された入力コンポーネントがあります。 ユーザーが入力ボックスに 15 文字を超えるテキストを入力した場合に、この境界線を赤色に変更する必要があります。 このことをチェックする条件を追加し、条件が有効な場合に入力の境界線のスタイルを 3px solid red
に設定してください。 入力欄にテキストを入力して試すことができます。
解答としては、下記になります。
Array.map() を使用して動的に要素をレンダーする
ToDoリストのようなユーザーが何個登録するかわからないような場合は、mapメソッドを使うことが多いようです。
mapメソッドは、配列の各要素に対して指定した関数を適用し、その結果から新しい配列を生成します。また、
配列の要素を一つずつ取り出し、指定した関数を適用します。
構文は以下のようになります:
[配列].map((value, index) => {
// 処理
return ...; // 新しい要素
});
[配列]
:map()
メソッドを呼び出す対象の配列です。(value, index) => { ... }
: 配列の要素ごとに実行される関数です。この関数は、配列の要素value
とインデックスindex
を引数として受け取ります。// 処理
: 配列の各要素に対して実行したい処理を記述します。return ...
: 処理結果として新しい要素を返します。この新しい要素は、map()
メソッドによって生成される新しい配列の要素となります。
と理解しています。
下記のような課題が出ました。
コードエディターで、MyToDoList
コンポーネントのほとんどが設定済みです。 制御されたフォームのチャレンジを完了しているのであれば、このコードの一部に見覚えがあると思います。 textarea
と button
があり、ユーザーの state を追跡するいくつかのメソッドがありますが、まだ何もページにレンダーされません。
constructor
の中で、this.state
オブジェクトを作成し、2 つの状態を定義してください。1 つは userInput
で、空の文字列として初期化してください。もう 1 つは toDoList
で、空の配列として初期化してください。 次に、render()
メソッドにある items
変数の隣の値 null
を削除してください。 その場所で、コンポーネントの内部状態に格納されている toDoList
配列全体をマップし、各アイテムの li
を動的にレンダーしてください。 文字列 eat, code, sleep, repeat
を textarea
に入力してボタンをクリックし、何が起きるかを確かめてみてください。
注: ご存知かもしれませんが、このようなマッピング操作によって作成される兄弟の子要素にはすべて、一意の key
属性を付ける必要があります。 心配はいりません。次のチャレンジでこのトピックを取り上げます。
解答が下記になります。
兄弟要素に一意のキー属性を付ける
Reactでは、liなどの要素を作成する際にどのアイテムが追加、変更、削除されたのか追跡するために”キー”を使用するようです。
この”キー”によってリストが何らかの方法で変更された時に再レンダリングの処理効率が上がるようです。
※キーは兄弟要素間でのみ一意であれば十分です。アプリケーションでグローバルに一意である必要はないようです。
下記のような課題がありました。
コードエディターに配列があり、いくつかのフロントエンドフレームワークと、Frameworks()
というステートレス関数型コンポーネントで構成されています。 Frameworks()
では、前回のチャレンジと同様に、配列を順序なしリストにマッピングする必要があります。 frontEndFrameworks
配列内の各フレームワークの li
要素を返すように、map
コールバックの記述を完成させてください。 今回は、それぞれの li
に key
属性を付けて、一意の値を設定してください。 また、li
要素には frontEndFrameworks
のテキストも含めてください。
通常は、レンダーされる要素を一意に識別するキーのようなものを作成します。 配列インデックスを使用する方法もありますが、通常は一意の識別子を使用するようにしてください。
解答はこのようになりました。
Array.filter() を使用して動的に配列を絞り込む
Reactでは、mapメソッドがよく使用されるようですが、他にもfilterメソッドを使用するようです。
名前の通り、条件に基づいて配列の内容を絞り込み新しい配列を返します。
※どこかで記事にもしようと思っていますが、イミュータブルなデータ操作が推奨されているようです。
イミュータブル:変更不可能な性質を持つことを指します。イミュータブルなデータやオブジェクトは、一度作成されたらその値や状態が変更不可能であり、新しいデータやオブジェクトが作成されることになります。イミュータブルなデータやオブジェクトは、変更操作によって元のデータやオブジェクトが直接変更されることはなく、変更操作によって新しいデータやオブジェクトが生成されます。
これによって、Reactでは、予期せぬデータが書き換わったりする可能性が少なるなるようです。
話を戻して、
filterメソッドの使い方としては、
「すべてのユーザーがプロパティ online
を持っていて、このプロパティを true
または false
に設定できる場合、次のように記述してオンラインのユーザーのみに絞り込むことができます。」
let onlineUsers = users.filter(user => user.online);
userというオブジェクトの中に、onlineというプロパティのみを抽出しているようです。
filiterメソッドを使用した課題として下記のようなものがありました。
コードエディターで、MyComponent
の state
がユーザーの配列で初期化されています。 オンラインのユーザーもいればそうでないユーザーもいます。 オンラインになっているユーザーのみが表示されるように、配列を絞り込んでください。 それには、まず filter
を使用して、online
プロパティが true
のユーザーのみを含む新しい配列を返してください。 次に、renderOnline
変数で、絞り込んだ配列全体をマップし、ユーザーごとに username
のテキストを含む li
要素を返してください。 前のチャレンジと同様に、必ず一意の key
も含めてください。
解答として以下のような記述をしました。
renderToString を使用して React をサーバーにレンダーする
今までのReactは、Reactコンポーネントをクライアント(webサイト)でレンダリングしてきました。
しかし、Reactは、JavaScriptのライブラリなのでNodeを使用するとサーバー上でも動くようです。
Reactには、renderToStringというメソッドが用意されているようです。
※React 16以前のバージョンでは使用されていたようですが、現在のReactは推奨されていないようです。
ReactDOMServer.renderToString(element)は、指定されたReact要素をその文字列形式のHTMLに変換します。これは通常、サーバーサイドレンダリング(SSR)の場合に使用されます。
ReactDOMServer.renderToStaticMarkup(element)は、renderToString()と同様にReact要素を文字列形式のHTMLに変換しますが、追加のデータ属性やReactの内部データ属性を出力しないようにします。静的なマークアップを生成する際に便利です。
これらのメソッドは、サーバーサイドでReactコンポーネントをレンダリングし、HTMLとして出力する際に使用されます。しかし、通常のクライアントサイドのReactアプリケーションでは、これらのメソッドは必要ありません。重要なのは、Reactのバージョンや使用しているフレームワークやライブラリに応じて、適切なメソッドを使用することです。最新のReactの公式ドキュメントやリソースを参照し、推奨される方法を確認することをおすすめします。
ということのようでした。
さらに、実世界のアプリでは、主に2つの理由でサーバーのレンダリングを使用する場合があるそうです。
実世界のアプリでは、主に 2 つの理由でサーバーでのレンダーを使用する場合があります。
https://www.freecodecamp.org/japanese/learn/front-end-development-libraries/react/render-react-on-the-server-with-rendertostring
1 つ目として、これを行わない場合の React アプリは、初めてブラウザーに読み込まれるときに、空に近い HTML ファイルと JavaScript の大きなバンドルで構成されることになりますが、 こうした構成は、ページのコンテンツのインデックスを生成しようとしている検索エンジンにとって理想的ではなく、ページが人々に検索されにくくなるかもしれません。 サーバーで初めて HTML マークアップをレンダーしてクライアントに送信する場合、初回のページ読み込みには、検索エンジンでクロールできるページのマークアップがすべて含まれます。
2 つ目として、レンダーされる HTML はアプリ全体の JavaScript コードよりも小さく、そのため初回のページ読み込みが高速になります。 それでも React はアプリを認識し、初回の読み込み後もアプリを管理することができます。
下記のような課題がありました。
解答としては、こうなっていました。
一旦、Reactの基礎が終わりました。
次回から、Reduxの記事を書いていこうと思います。
今日はここまでです。