React.jsに関するQ&A(よくある質問)をまとめました
Reactでお困りの際はこの記事で問題解決を試みて下さい。
これらの質問はReact初学者が質問する、よくある質問をまとめた記事となります。
※注意点
当記事の質問に対する回答は、必ずしも最善の方法という訳ではございません。
最も簡単で適切な方法を解説しております。
Reactよくある質問
最も多い質問
- Reactとは何ですか?
-
Reactは2013年にFacebookのソフトウェアエンジニアの『Jordane Walke』氏によってオープンソースプロジェクトとしてリリースされ、Netflix、Uber、Airbnbなどの大手企業にも広く使用されました。 Reactはフレームワークではなく、具体的にはライブラリです。 Webアプリやモバイルアプリ開発に使用できます Reactの人気は操作が便利で、インターフェースを作成する際の柔軟性と自由度が最大であることによるものです。 dev-k.hatenablog.com
- Reactの長所は何ですか?
-
ReactはMVC(Model-View-Controller)アーキテクチャに従います。 アーキテクチャのV(ビューパーツ)でもありJavaScriptフレームワークの1つとも呼ばれたりします。 ユーザーインターフェイス(UI)ライブラリの多くの利点がありタスクをより適切に実行するのに役立ちます。 Reactは仮想DOMを使用してビューをレンダリングします。 仮想DOMは、実際の標準DOMの仮想表現です。 Reactアプリでデータが変更されるたびに、新しい仮想DOMが生成(作成)され、仮想DOMの作成はブラウザ内でUIをレンダリングするよりもはるかに高速です。 したがって、仮想DOMを使用するとアプリの効率が向上します、そのためReactは優れた効率を提供します。 Reactのもう一つの長所はSEOに適しております。 Reactは、開発者がさまざまな検索エンジンで簡単にナビゲートできる魅力的なUIの開発を容易にします。 また、サーバー側のレンダリングも可能となっておりこれはアプリのSEOを向上させるのにも非常に役立ちます。 Reactにはライブラリの巨大なエコシステムがあり、要件に基づいて最適なアプリケーションを開発するためのツールやライブラリ、およびアーキテクチャを自由に選択可能です。
- Reactの短所は何ですか?
-
Reactは単なるライブラリであり、完全なフレームワークではありません。 Reactでは、RailsのようなMVCフレームワークへのユーザーインターフェイスの統合に関する複雑な構成をするには知識が必要となります。 Reactエコシステムはかなり巨大です、理解するのに時間がかかります。 ReactはインラインテンプレートとJSXを使用しますが、これは非常に困難であり障壁として機能する可能性があり、またコーディングが複雑になる場合もあります。 最も欠点の1つは、開発ペースが速すぎる事です、つまりライブラリが絶えず進化している為、開発者はプロセスや新しいメカニズムを再学習しながら付いていくのは非常に困難であり、不満を持つ方は多くいらっしゃいます。 しっかりとした適切なドキュメントが不足しています、他のライブラリやツールだけでなくReact自体も定期的に更新されます。 しかし残念ながら、これには欠点があります。アップデートや新しいリリースの数が多いため、完全なドキュメントを作成するのに十分な時間がありません。 開発者には詳細をカバーしていない、まばらなテキストガイドしか残されていません。 ですので開発者は独自で作成しているので、貧弱なリソースが多かったりします。 下記と合わせてお読み下さい。 dev-k.hatenablog.com
- Reactの機能はなんですか?
-
Reactの主な機能は次のとおりです。 ※最新であるReact v18機能も含めます。 • JSX • 仮想DOM • コンポーネント • パフォーマンス • シンプルさ • 一方向のデータフロー (またはデータバインディングとも呼ぶ) • 同時レンダリング(並行性) • 自動バッチ処理 • 状態管理 • サスペンス機能 • フック • React Native React v18新機能については下記で解説ております。 dev-k.hatenablog.com
- なぜReactを使用する?
-
日本ではあまり、馴染みのないフレームワークかもしれませんが、React.jsは2021年に世界中の開発者の間でWeb開発サービスに最も使用されたフレームワークです。 Statistaからのレポートのデータによりますと、Reactは40.14%、JQueryは34.43%、Angular.jsは22.96%、Vue.jsは18.97%(以下略)でした。 ※これは世界中の使用者です。 ReactはインタラクティブなUIの開発を可能にする、効率的なJavascriptフレームワークでありWebに優れた柔軟性と使いやすさを統合し、優れたアプリケーションを構築する為のJavaScriptライブラリでもあるからです。 Reactの使用率は大幅に増加しており、今後さらに成長すると予想されています。 企業はスキルに精通した開発者を探すため、React開発者を採用する需要は高まります。 個人的な意見としてですが、Reactの開発者として長年やっていますが2022年に入ってから、日本でのReactを学ぶ学習者が増えていると感じております、それはSNSや実際に学びたいと言ってる声を聞いたりしているからです。 すぐに習得はできませんが、他のWeb開発技術よりも短時間でReact.jsを学ぶことができます。 開発者がReact.jsを使用する他の理由はいくつかあります。 それは効率的で宣言型のオープンソースJavascriptライブラリで柔軟性などが含まれます。 このような側面によって、Webアプリの開発が容易になり、スケーラブルでシンプルなフロントエンドアプリケーションが可能となるからです。 React.jsは、小規模および大規模な組織の両方に役立ち、使いやすい応答性の高いJavaScriptライブラリです。
- Reactの代替えはありますか?
-
はい、ございます まずはReactの代替品を探している場合は、最初にそれらが必要な理由を理解する必要がありますので、よく考えてから切り替えを検討下さい。 ReactJSの代替可能な人気のあるものは下記となります。 • Inferno JS Inferno.jsは効果的なUIを作成するためのReactのようなライブラリを提供する高速でパフォーマンス重視のJavaScriptツールです。 • Xamarin 正式名称は『Powered by Microsoft Xamarin』でReactの無料のオープンソース代替手段となります。 iOS、Android、watchOS、tvOS、macOS、およびWindowsアプリに対応しています。 パフォーマンス重視のアプリケーションを作成するために使用される方が多いです。 • Ember JS Ember.jsは、クライアント側のレンダリングテンプレート構造になっておりURLサポートを提供するReactの人気のある代替手段です。 • Flutter Flutterは、Googleが提供する主要なオープンソースのUIフレームワークです。 開発者は特定のコードベースを介し、モバイル、デスクトップ、およびWeb用のクロスプラットフォームアプリを作成できます。 • Backbone JS Backbone.jsは、Webアプリケーションに構造を提供する人気のあるJavaScriptライブラリとなっています。 1つのJSライブラリに依存している為、非常に軽量です。 • Vue JS Vue.jsは、Reactの優れた代替手段として、より高速でスマートなアプリを簡単に作成でき、シンプルでありながら強力なJavaScriptフレームワークです。 モジュールであり、Reactと比較して軽量となっています。 • Angular JS Angular.jsは、高速で効果的かつ効率的なWebアプリケーション開発およびモバイルアプリケーション開発が可能でWeb、デスクトップ、およびモバイルアプリの構築に役立ちます。 Googleが提供するオープンソースフレームワークです。 • Preact Preactは、精度とコンパクトさを備え持つ単純な実装を備えた最速のV-DOMライブラリの1つです。 Web/モバイルアプリケーションを作成するためのReactライブラリの軽量オプションになります。 • Aurelia Aureliaは、アプリケーションとコンポーネントをシームレスな統合を提供する人気のあるツールです。 ES2016を使用して作成されており、Web、モバイル、およびデスクトップアプリケーションを作成するための強力なツールで人気があります。 • Riot JS Riot.jsは、コンポーネント駆動型のシンプルなUIライブラリです。 非常にReactに似ていますが、高速な仮想DOMを備えておりHTMLで複雑なビューを作成するのに役立つカスタマイズされたタグを提供しています。 カスタムタグを使用し効果的なUIを作成し、初心者が簡単に始められるので人気のあるライブラリです。 • React-lite React-liteは、Reactのサブセットだと思って下さい。 スクリプトのサイズを小さくするために最適化されたReactの並列実装となっており、機能操作にReactDOMサーバーを利用しています。 ReactをReact-liteに置き換えることにより、JavaScriptバンドルのサイズが大幅に減少します。 jsファイルのバンドルサイズを減らしたいモバイルサイトにとっては依然として優れた選択肢と言えます。 • Cycle.js Cycle.jsは、Reactの優れた代替手段として、リアクティブおよび機能ストリームできるリアクティブJSフレームワークです。 リアクティブプログラミング(RP)は、非同期データストリームを使用したプログラミングです。 その関数型プログラミングの概念は、関数が入力と出力のみを持ち、エラーが最小であることを保証致します。 • Svelte Svelteは、UIを作成するための有名な無料のオープンソースコンパイラです。 アプリケーションの状態が変更されるとすぐにDOMを更新し、より良い反応性、拡張性、速度を提供し軽量で既存のJSライブラリを活用します。 仮想DOMはなく、記述する必要のあるコードも少なく、複雑な状態管理ライブラリもございません。 その為Svelteは小規模なアプリケーションや小規模なチームに最適となっています。 • Mithril JS Mithril.jsは単一ページのアプリを作成するための、クライアント側のJavaScriptフレームワークです。 サイズが小さく、パフォーマンスが高速となっておりルーティングおよびXHRユーティリティを提供します。 習得が比較的容易です、読み込みが非常に速くてAPIが同業他社と比較しても小さくなっています。 仮想DOMを使用するので、そのテンプレートが最初にコンパイルされます。 • Vanilla JS Vanilla.jsはJQueryのような他のライブラリなしでプレーンJavaScriptを使用します。 つまり純粋なJavaScriptを示しています。 純粋なJSを深く知っていると、複雑な問題を解決できるエンジニアになれる事は間違いありません。 フレームワークを嫌う人はほとんどいないと思います しかし誰もがJavaScriptフレームワークを好むわけではなく、常に適用できるわけでもありません。 フレームワークは必ずしもあなたのスタイルやニーズに合うとも限りません、つまり場合によってはフレームワークから切り離したりすることもできます。 コードが複雑化していない、小さくて単純なアプリケーションの場合に理想的です。
- ReactとReact Nativeの違いは?
-
ReactNativeは、ある意味でReact.jsと非常に似ています。 React.jsは、UIの構築に使用されるフロントエンドのオープンソースJavaScriptライブラリです。 ReactNativeは、開発者がAndroidやiOSなどのプラットフォームでReactを使用できるようにするオープンソースのモバイルフレームワークです。 ではその他の違いを説明します。 ReactNativeでは、JavaScriptでWindows、Android、iOSなどのさまざまなプラットフォームで実行できる再利用可能なコンポーネントを備えたネイティブモバイルアプリケーションを開発するのに非常に優れたクロスプラットフォームです。 ReactNativeを使用してMVPを構築している場合は、開発時間を大幅に節約できます 1つのコアAPIを利用して、iOSとAndroidの両方に同じAPIを提供することが知られており、iOSとAndroidの両方でアプリを実行できるようにします。 ホットリロード機能や優れたUIなどReact.jsがもたらす、すべての利点を兼ね備えておりモバイルアプリをリロードする柔軟性があるので、それによって貴重な開発者の時間を大きく節約し、開発プロセスを加速します。 つまりReactNativeを使用すると、アプリをより速く構築可能です。 アプリのレンダリングにはHTMLを使用しません。同様に機能する代替の独自のコンポーネントを提供しています。 React.jsではコードのレンダリングに仮想DOMを使用します。 そして、コンポーネントの再利用性が強化され大幅な時間が節約されます。 React.jsではサーバー側のレンダリングが可能なためWebページやアプリのSEOを強化しより優れたUXを実現でき、開発者ツールの巨大なエコシステムとなっています。 ツール、コンポーネントライブラリ、IDE、コードエディタの拡張機能、Webブラウザなどの大規模なエコシステムを作成した開発者の巨大なコミュニティがあり、様々なツールと拡張機能が利用できます。 React.jsを使用すると、動的なアプリケーションの作成が簡単となります、それは複雑なコーディングを必要とせず、より少ないコーディングを提供しより多くの機能を提供します。
- なぜブラウザはJSXを読み取れない?
-
WebブラウザではJSXを直接読み取ることはできません。 これは、通常のJSオブジェクトのみを読み取るように構築されており、JSXは通常のJavaScriptオブジェクトではないためです。 つまりブラウザは母国語であるJavaScriptのみしか直接は読み取ってはくれません。
- ブラウザはどのようにしてJSXファイルを読み取る事ができますか?
-
JSXはJavaScriptオブジェクトのWebブラウザで理解できる形式に変換する必要があります。 ブラウザがJSXを読み取れるようにするには、『babel』を使用して、JSXファイルをブラウザが理解できるネイティブのJavaScriptオブジェクトとHTMLに変換してから渡してあげなければいけません。 Babelは、最新のJavaScript(ES6)を古いES5のJavaScriptに変換するJavaScriptトランスパイラーです。 すべての最新のJavaScript機能はまだすべてのブラウザでサポートされているわけではありません。 ES6機能をすべてのブラウザで理解できるES5にトランスパイルするために使用され、BabelではJSXをサポートしております。 つまりBabelはES6のトランスパイラーでもありJSXトランスパイラーでもあるのです。 あなたがcreate-react-app(CRA)を使用している場合に限り、CRAではBabelが組み込まれているので別途、統合する必要性はありません。 JSXを使用しない場合はBabelは必要ありません。
- Reactプロジェクトを開始するにはどうすればいいですか?
-
Reactを使用する方法はたくさんあります。 Reactの学習を開始する上で最も簡単な方法は、HTMLファイルに直接Reactを書き込むことです。 HTMLのheadタグに3つのスクリプト(CDN)を含めると使用可能です。 3つのScriptには『Reactの本体』『DOM操作用react-dom』それに加え『JSのトランスコンパイラ』である『Babel』を読み込んであげます。
<head> <script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> </head>
この方法でのReact使用では、テスト目的つまり学習目的であればお勧め致します。 ですが本番環境でのReact構築をセットアップしていかなければいけません。 一般的によく知られており、使用される『Create React App』ツールを使用します。 単一ページのReactアプリケーションを作成するために公式でサポートされている方法です。 構成なしの最新のビルドセットアップを提供しています。 つまりwebpackやBabelなどのツールをインストールまたは構成する必要はありません、これらは事前に構成されています。 CRAを使用するには、Nodeパッケージマネージャー(npm)を使用するため、Node.jsのインストールが必要になります。 コマンド(CLI)でcreate-react-appをインストールします。npm install -g create-react-app
create-react-appがインストールされたので、次のコマンドを実行するだけで新しいReactプロジェクトを作成できます。npx create-react-app my-react-app
WebpackとBabelでReactプロジェクトをセットアップしていく方法がございます。 この方法はcreate-react-appを使用したくない場合に最適です、CRAではWebpackとBabelが事前に構成されており、コマンド1つでReactをすぐに始められますが、独自でそれらをセットアップしプロジェクトを構築していかなければなりません。 つまり、ある程度の専門的知識も必要とします、WebpackとBabelそれらが何をしているのか、そしてそれらがReact.jsとどのように相互に関連しているかを理解する必要があります。 dev-k.hatenablog.com dev-k.hatenablog.com 初学者の場合、CRAを使用しReactを始める事を強くお勧めします。
- リアルDOMとReactDOMの違いは何ですか?
-
実際のDOMと同様に、仮想DOMでもツリー構造として表されます。 唯一の違いは、変更のたびに実際のDOMではなく仮想DOMが更新されることです。 1.リアルDOMはHTMLから直接更新が可能です。 2.要素が更新されたDOMは1度にツリー全体を再構築し更新します、ですのでどうしても更新時間がゆっくりで遅くなります。 3.あまりにも多くのメモリを浪費します。 ツリー全体を再構築する必要がないため、パフォーマンスの向上に役立ちます、これはReactは仮想DOMツリーを更新しますが、実際のDOMツリーは変更しません。更新後は現在の仮想DOMと変更後の仮想DOM同士で比較します、比較後に変更されたオブジェクトを認識しリアルDOMへと反映します。 『VirtualDOMdiff』アルゴリズムのおかげで、Reactでは各UIは個別のコンポーネントであり、各コンポーネントには独自の状態があります、最新のデータで再レンダリングしても状態が失われることはありません。 仮想DOMではメモリ使用量を削減し、より高速で簡単にレンダリング可能です。 違いを詳しく学びたい方は下記で解説しております。 dev-k.hatenablog.com
- Reactでのcreate-react-appとはなんですか?
-
create-react-app(CRA)は、ビルド構成なしでReactアプリを作成するためのReact(Meta)の公式CLI(コマンドラインインターフェイス)です。 WebpackやBabelなどのツールをインストールしたり構成したりする必要はございません。 これらはCRAに全て付属されております。 簡単にインストールができ、コマンド1つでReactプロジェクトを開始する事ができる非常に便利なツールとなっております。 npmまたyarnのコマンドを通してインストール可能です。 CRAでは、何かを変更するとアプリケーションを自動的にリロードするウォッチャーを備えたWebpackローカル開発サーバーが起動します。 ES6およびES7の一連の機能をサポートする独自のBabelプリセット(babel-preset-react-app)が付属しています。 スタイリングでは、必要なCSSファイルをインポートするだけでスタイルを追加でき、アプリケーションをビルドすると、すべてのCSSファイルが1つのバンドルに連結され、ビルドフォルダーに追加されます。 CSSモジュールもサポートされているので、CSSセレクターの名前競合を回避できます。 CRAは開発時間を何時間も節約できる、効率の良いツールです。 dev-k.hatenablog.com
- Reactでのルーティングは従来と、どのように異なりますか?
-
まず従来のルーティングでは、ユーザーはナビゲーションバーで提供されるリンクを使用し、さまざまなページにアクセスしたり、フォームで提供されたボタンを送信したりできます。 ユーザーがそのリンクまたはボタンをクリックすると、表示が変更されるとURLが更新されます。 そしてURLが変更されるたびに、アプリケーションのサーバーにリクエストをするのがブラウザ本来の動作にとなります。 サーバーではURL内のパス名をチェックしてから、それに応じて新しいHTMLページで応答します。 そのサーバーがURLのパス名に基づいて要求を処理するプロセスが、従来のルーティングとなっております。 従来のルーティングでは応答が表示されるまでにかなりの時間がかかる可能性があります、それはページ全体が更新されるからになります。 では、レンダリング時間を短縮し常に一定を保ち、ページ全体を更新する必要がないようにするにはどうすれば良いでしょうか? そこでクライアント側ルーティングまたはReactRouterライブラリが使用されます。 ReactRouterは動的ルーティングを使用します。 ReactRouterと動的なクライアント側ルーティングにより、ユーザーがナビゲートするときにページを更新することなく、ナビゲーション付きの単一ページのWebアプリケーションを構築できます。 つまりルートに対して要求が行われるたびに、この要求はサーバーに送信される事はありません。 代わりとして、ページにロードされたJavaScriptがルーティングプロセスを処理してくれます。 ReactRouterは、コンポーネント構造を使用しコンポーネントを呼び出し、適切な情報を表示してくれるので、Webページの一部のみが更新されるため、これはページ全体が更新されないという事になります。 ですのでクライアント側のルーティングでは、URLが更新されるたびにページの更新は一切行いません。 従来のルーティングと比べ、クライアント側のルーティングは高速なページ遷移を実現させました。 dev-k.hatenablog.com
- AJAXはReactでも使用可能ですか?
-
はい、可能です。 ですがReactはJavaScriptベースのライブラリであり、HTTPリクエストを行う機能は元々ありません。 しかしHTTPリクエストの作成は、Webアプリケーションの基本的な部分です。 それを実現させるには、サードパーティのライブラリを使用する必要があります。 ReactアプリにHTTP呼び出しを行うために利用できるライブラリは様々あります、それは下記となります。 • Axios • Fetch • Superagent • React-axios • Use-http • React-request Reactアプリでデータを送信する場合、開始する最も簡単な方法は、ブラウザのFetchAPIの使用です。 FetchはReactだけでなく、AngularやVuejsなどの他のフレームワークからも使用できます。 フックでAJAX呼び出しを行う場合は、useStateとuseEffectフックを組み合わせ、呼び出します。 フックでのFetch使用方法は下記で解説しております。 dev-k.hatenablog.com
- ReactでjQueryを使用するにはどうすればよいですか?
-
※統合する前に注意点がございます、どうかReact内部でJQueryを使用しないようにしてください。 React内でjQueryを使用することが推奨されない理由についてはございます。 それはReactでは実際のリアルDOMではなく、仮想DOMと呼ばれる概念を使用している為です。 つまり仮想DOMの外部でブラウザのDOMを変更すると、React状態、イベント、UIレンダリングなど様々なレンダリング処理はされず変更は認識されなくなる可能性があります。 ですが、使用する事は可能ではあります。 基本的にはnpm経由でJQueryをインストールします
npm install jquery
jqueryをjqueryパッケージの$としてインポートします。import $ from "jquery"
もし、あなたがReact内部でJQueryを使用する事を検討しているのであれば、両方が使用されている場合は、開発者はそれぞれが何をしているのか、そしてもう一方がそれをどのように処理するのかをしっかりと知っておく必要があります。 バグが発生する可能性があるので、適切に扱って下さい。
- クラスコンポーネントは学ぶ必要ありますか?またはスキップしても大丈夫ですか?
-
これに関する質問は、人によって意見が違います。 フックから学ぶべき、またはクラスコンポーネントはReactの一部だからしっかりクラスコンポーネントから学ぶべきだ、と様々な意見が飛び交ってます。 当ブログ主がReact学習を始めた時は、フックがまだ導入されていなかったので、強制的にクラスでしたが…。 これだけは言えます、非常にまれですが、選択の余地がなく、クラスを使用しなければならない場合があります。 ですが確率で言えば、現代では99%はフックです。 学習の際にReactに関連する概念、つまりライフサイクルや仮想DOM、フックの便利さなどが、いまいち理解できない場合は、クラスコンポーネントからしっかり学習すれば解決する場合があります。 あなたの学習環境に合わせて、適切に選んで下さい。
機能に関する質問
- JSXとは何ですか?
-
JSXはJavaScriptXMLの略語となります。 JSXは、Reactで使用されるXML/HTMLに似た構文であり、ECMAScriptを構文拡張して、XML/HTMLに似たテキストをJavaScript/Reactコードと共存できるようにし、全機能を備えております。 JavaScriptコード内にHTMLコードを記述するための構文です、つまりそれらを1つのファイルに混在された構文となります。
const name = "React"; const App = <h1 className="#">Hello, {name}</h1> // Hello, React
上記ではHTMLをJavaScriptコードとして埋めこんでおり、JSXを示しています。 少し奇妙な感じもしますが、非常に便利でもあります。 Reactは必ずしもJSXを使用する必要はありませんが、ほとんどの開発者は、JavaScriptコード内でよりユーザーエクスペリエンスを提供することに気づいています。 JSXがReact.jsの重要な部分である理由となります。 dev-k.hatenablog.com
- Reactコンポーネントとはなんですか?
-
Reactのコンポーネントは、各コンポーネントは同じ構造で存在しますが、互いに独立して機能し再利用可能なUIです。 つまりコンポーネントはUI/UXの実行可能な部分であり、JavaScript関数と同じ目的を果たしますが、単独で機能し、HTMLを返します。 コンポーネントには、基本にクラスコンポーネントと関数コンポーネントの2つのタイプの種類があります。 古いReactコードでは、クラスコンポーネントが使用されている事がほとんどです。 現代ではReact v16.8以降で新しく導入されたフックと一緒に関数コンポーネントを使用しています。 Pure(純粋)コンポーネントと高次(HOC)コンポーネントもございます。
- クラス・関数コンポーネントの違いは何ですか?
-
関数コンポーネントとクラスコンポーネントの違いの質問に対する標準的な回答は、クラスコンポーネントではライフサイクルメソッドまたはsetState()などの機能を提供しますが、関数コンポーネントではサポートされておらず提供していない事です。 最も明らかに違うのが、構文に関する違いです。
//クラスコンポーネント class App extends React.Component { render() { return <h1>Hello, world</h1>; } }
クラスコンポーネントは、React.Componentを拡張するクラスとなります。//関数コンポーネント const App = () => { return <h1>Hello, world</h1>; }
関数コンポーネントはJavaScript関数です。 そしてクラスコンポーネントでイベント処理を行う際は構文をさらに記述が必要となります。//クラスコンポーネント class App extends React.Component { constructor(props) { super(props); this.setState({ title: 'This is the first test' }); } render() { return <div>{this.state.title} </div> } }
constructor()とsuper()さらにthis.state{}の記述が必要の場合もあります。 関数コンポーネントに比べて、どうしてもコード行が増えてしまいます。 関数コンポーネントと違いクラスコンポーネントの動作は少し異なります、それは上記のコードを見ると『this』キーワードがある事に気付くかと思います。 クラスコンポーネントではこの『this』の挙動や操作が非常に厄介であり、常にthisの事を考えながらコードを書いていく必要があるのです。 props(小道具)の渡し方も異なります。//関数コンポーネント const App = props => { return <h1 >Hello, {props.name}</h1>; }
関数コンポーネントでは『props.name』を使用して、関数の引数としてpropsを渡します。//クラスコンポーネント class App extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
前述した通り、必ず『this』を追加し小道具を参照しなければいけません。 クラスコンポーネントはより複雑です。 それらは、(constructorも含む)React.Componentのインスタンスであり、状態とライフサイクルを操作するためのメソッドの複雑なシステムとなっています。 関数での呼び出しは、クラスを作成するよりも遥かに短時間で済みます。 現代ではフックの導入のおかげで、関数コンポーネントのみを使用してアプリ全体を構築できます。 dev-k.hatenablog.com
- Reactのprops(小道具)とは何ですか?
-
props(小道具)とは、タグの属性の値が格納されるオブジェクトの一種ですが、『小道具』という言葉そのものは『プロパティ』を意味します。 機能はHTML属性と非常によく似ていますが、小道具は読み取り専用コンポーネントとなっています。 小道具を使用して、あるコンポーネントから別のコンポーネントにデータを渡すことができます、コンポーネント内にpropsという属性を追加可能となります、 コンポーネント内の小道具は不変である為、1度渡された値を変更する事は一切できません。 ですので、読み取り専用である事です。 親から子コンポーネントへデータを渡す際は、一方向となっており、逆から渡す事はできません。 つまり子から親コンポーネントは小道具は渡せません。 小道具は、下記のようなあらゆる種類のデータを渡すために使用されます。 • String • Array • Integer • Boolean • Objectsまたは, Functions
- propsの値を更新できますか?
-
いえ、できません。 小道具はデータの読み取り専用です、他のコンポーネントへ渡された値を変更する事はできません。 変更する際は、渡された子のコンポーネントではなく親のコンポーネントで変更するしかありません。 それは小道具では親コンポーネントで保持されているからです。
- Reactのchildren小道具とは何ですか?
-
コンポーネントが小道具を受け取りレンダリングするchildren機能は、Reactの最も価値のある機能の1つです。 それは再利用可能なコンポーネントの作成が非常に簡単になります。 つまりprops.childrenプロパティを使用すると、親が呼び出されたときに変更できる、汎用テンプレートコンポーネントを作成できます。 これは、親コンポーネントが子コンポーネントで必要なものをすべて渡すことができるという事になります。
const Picture = (props) => { return ( <div> <img src={props.src}/> {props.children} </div> ) }
コンポーネントが呼び出されるたび{props.children}に表示されます。
- Reactのstate(状態)とは何ですか?
-
Reactコンポーネントでは、『state(状態)』と呼ばれている組み込みのオブジェクトがあります。 コンポーネントがどのようにレンダリングおよび動作するかを決定するオブジェクト(状態)でコンポーネントにより管理されます。 つまりは動的でインタラクティブなコンポーネントを作成できるようにするものが『状態』となります。 本来、関数が終了すると通常の変数は役目が終えると『消える』一方で、状態変数はReactによって常に保持され、状態が変更されるとコンポーネントが再レンダリングされます。 この状態変数はクラスでの状態です。 Reactの関数コンポーネントはプレーンなJavaScript関数となります、関数が評価されるたびにローカル変数が初期化されるため、ローカル変数に状態を保持することはできません。 ですがReact 16.8から、開発者がステートフルな関数コンポーネントを記述できるようにReactフックをを導入しました。 関数コンポーネント内で状態変数を使用するにはこのuseStateメソッドを使用し、状態を更新します。
- 制御・非制御コンポーネントとは何ですか?
-
Reactで制御されるコンポーネントは、フォームデータがコンポーネントの状態によって処理されるコンポーネントの事を指します。 制御されていないコンポーネントとは、フォームデータがDOM自体によって処理されるコンポーネントです。 これは、Reactの状態によってコンポーネントが制御されているのか、もしくはReactの状態によって制御されいないのかの違いとなります。 制御されていないコンポーネントは従来のHTMLフォームに非常に似ております。 それはフォーム要素のインスタンスを参照してDOMから値を取得するためです。 機能での違いを詳しく学びたい方は下記でも解説しております。 dev-k.hatenablog.com
- Reduxとは何ですか?
-
Reduxは、アプリケーションの状態を管理するために使用されるオープンソースのJavaScriptライブラリです。 ReduxとReactは一般的にはよく一緒に使用されますが、互いに独立しています。 ReactコンポーネントはReduxストアからデータを読み取り、アクションをストアにディスパッチしてデータを更新できます。 つまり、Reduxはアプリ内の変数の状態を保存するための単なるストアとなります。 状態の管理をしてくれる方法でもあり、すべてのコンポーネントからアクセスできるストレージであるとも言えます。 アクセスは『レデューサー』と『アクション』を介してアクセスします。 よくあるカウンターコンポーネントの例で流れを説明します。 まずはレデューサーからストアを作成します、値を初期化し、アクションをディスパッチして状態の値をインクリメントする流れとなります。 ReactでReduxを使用する場合、状態を解除する必要がなくなります。それにより、どのアクションが変更を引き起こしたかを簡単に追跡できます。 コンポーネントのデータ共有するための状態やメソッドは必要ありません、全てReduxによって処理される為です。
- setStateとuseStateの違いは?
-
useState()は、関数コンポーネントに状態変数を含めることができるフックとなり、状態はコンポーネント自体によって作成および維持されます。 前の状態を更新する必要があるのでuseState()フックを使用し、更新します。 クラスコンポーネントで状態を使用するには、状態オブジェクトを作成する必要があります、this.setState()で状態を変更します。
// useState() const [count, setCounter] = useState(0);
//setSate() constructor() { super(); this.state = { val: 0, }; } componentDidMount() { this.setState({ val: this.state.val + 1 });
クラスのsetState()とは異なり、useState()では状態はオブジェクトである必要はありません。 関数コンポーネントでのuseState()は、複数の呼び出しを実行することにより、必要な数の状態を持つことができ、なおかつ状態の遅延初期化が可能です。 useState()はフックなので使用するときは、フックのルールに従いながら書く必要があります。 状態管理はクラスコンポーネントと非常によく似ております、ですが更新による大きな違いはございません。
- Reactアプリをスタイリングする一般的なものは何ですか?
-
Reactでのコンポーネントスタイルを設定していく方法は様々あります。 外部コンポーネントにスタイルを追加したり、コンポーネント内のJSX要素に最小限のスタイルを割り当てたりする場合があります。 • インラインCSS • 通常のCSS • CSS in JSまたはTailwind.cssなどのライブラリ • CSSモジュール • Sass&SCSS • Less • Stylable これらにはそれぞれ長所と短所があり、それはすべて個人または会社の好みとアプリケーションの複雑さよって依存します。 また、どのようなスタイリング戦略を使用する場合でも、基本的にはCSSです。 いつものようにCSSを書くことができますが、他のライブラリは、独自のスタイリングにも役立つ機能を提供しております。 Reactでのスタイリング方法は下記で解説しております。 dev-k.hatenablog.com
- Reactではどのようにイベント作成しますか?作成方法は?
-
Reactには、DOM要素でのイベントの処理と非常によく似た独自のイベント処理システムがあります。 Reactのイベント処理システムは、一般的に合成イベントとして知られています。 Reactを使用した、イベント処理は本来のDOMイベントの処理と構文上の違いがございます。 • Reactイベントは、小文字ではなくキャメルケースとして名前が付けられます。 • JSXでは、関数は文字列ではなくイベントハンドラーとして渡されます。 皆様がよく馴染みのあるHTMLのイベントは下記のように記述するかと思います。
<button onclick = "showMessage()" > Hello, welcome. </ button>
Reactでのイベント宣言は下記のように記述します。<button onClick={showMessage}> Hello, welcome. </button>
いくつかの違いを見て取れるかと思います、まずonclickの『C』が大文字になってる事に注意して下さい、つまりonclickの代わりとして『onClick』を使用します。 そして渡す際は、波括弧{}で囲います。 Reactでは、デフォルトの動作を防ぐために『false』を返すことはできません。 ですので、デフォルトの動作を防ぐには『preventDefault』イベントを明示的に呼び出す必要があります。const App = () => { function handleClick(e) { e.preventDefault(); console.log('Hi, welcome.'); }
- Reactでのキーの重要性とは?
-
Reactコードを1度でも書いた事のある方でしたら、おそらく下記の警告を見た事があるかと思います。
Warning: Each child in a list should have a unique "key" props. // 警告: リストには各、子は一意な"キー"小道具をもつ必要がある
ほとんどのReactアプリでは、mapメソッドを使用し配列リストを表示します。 Reactでは『キー』は一意の識別子であり、リストから変更、更新、または削除されたアイテムを識別するために使用されます。 コンポーネントを動的に作成したり、ユーザーがリストを変更したりする場合に非常に便利となっています。 key小道具をタグに追加するだけですが、はたしてそれがそれほど重要のものなのか?疑問に持つ方もいらっしゃるかと思います。 子がキーを持っている場合、Reactはそのキーを使用して、古いツリーの子と新しいツリーの子を照合します。<li key={0}>アイテム0</li>// 新しいアイテム <likey={1}>アイテム1</li> <li key={2}>アイテム2</li> <li key={3}>アイテム3</li>
こうするこでReactは他のアイテムが移動したことをすぐに認識します。 キーを使用せずに、リストアイテムの順序を変更した場合に、例えばリストを並べ替えたり、アイテムを削除したりなどした場合、アプリケーション自体にはエラーをスローする事はありませんが、奇妙なことが起こったりします。 つまりキーがなくてもバグは発生しません、しかしリストは奇妙な異なった動作をしたりするわけです。 キーの主な目的は、Reactが要素を互いに区別し、仮想DOMと実際のDOMを区別する際のパフォーマンスを向上させる事になります。
- Reactでのコメントを書く方法は?
-
Reactコンポーネント内にコメントを追加したい場合は、JavaScriptのコメントに非常に似ています。
const App = () => { //これは行コメントです return <div>React App </div> }
/*ブロックコメントは前後に追加できます*/ アスタリスクとスラッシュを使用します。const App = () => { /*これはブロックコメントです *これは複数の行に分割できます *したがって、複数行コメントとも呼ばれます * / return <div> React App </div> }
• JSX内でのコメント JSX内にコメントを追加するのは少し異なります。 JSXはHTMLのように見えるので< !-- -- >、コメントにタグを使用できると思われるかもしれませんが、これはJSXでは機能しませんのでご注意下さい。 JSXブロック内にコメントを追加する場合は、波括弧内{}にコメントを含める必要があります。const App = () => { return ( <div> { //これはJSX内の行コメントです } <p>段落です</p> <p>段落です</p> <p>段落です</p> </div> ) }
複数行のコメントは上記にブロックコメントに変えるだけとなります。const App = () => { return ( <div> { /*これは 複数行のコメント JSX内*/ } <p>段落です</p> <p>段落です</p> <p>段落です</p> </div> ) }
記号の入力を覚えて手動でも良いですが、コメントを追加するショートカットがあります。 • VS CodeエディタCtrl + /
Cmd + /
• ATOMエディタCtrl + Alt + /
Cmd + Alt + /
- ReactRouterを使用したコンポーネント間のデータ受け渡しをするには?
-
ReactRouterを使用したデータの受け渡しは、stateという名前のprops(小道具)を使用し、Linkコンポーネントを介して状態を渡すことができます。
import { Link } from 'react-router-dom'; const myData = { name: 'Taro', age: 30 } /* ... */ <Link to="/some-where" state={myData}>Link </Link>
Linkコンポーネントを介して渡されるデータを取得するには、useLocation()フックを使用します。import { useLocation } from 'react-router-dom'; /*...*/ const location = useLocation(); const data = location.state; console.log(data);
- ReactでのRouterの必要性はなんですか?
-
ReactRouterは、主にシングルページアプリケーション(SPA)Webアプリケーションの開発に使用されます。 ReactRouterはすべてのReactプロジェクトの44%が含まれています。 この統計の事実だけで、ReactRouterはReact開発者にとって不可欠なものである事は間違いありません。 ReactRouterは、単一ページアプリケーションで複数のビューを表示するために重要な役割を果たします。Reactルーターがないと、Reactアプリケーションで複数のビューを表示することはできません。 皆様が使用してるであろう、FacebookやInstagramなどのほとんどのソーシャルメディアやNetflixなどのWebサイトは、複数のビューをレンダリングするためにReactRouterを導入し使用しています。 ReactRouterなしでReactシングルページアプリケーションに複数のビューを表示することはほとんど不可能であることに注意してください。
- Reactで本番モードにするには?
-
本番ビルドを含むビルドディレクトリは、ルートプロジェクトフォルダ内に作成されます。 下記のコマンドを実行して、静的サーバーでビルドバージョンを提供します。
npm install -g serve serve -s build
アプリは本番モードで実行されます。 本番モードで実行されているかしっかりと確認したい場合は、Google Chromeの拡張機能である『ReactDeveloperTools』を使用します。 ブラウザ拡張機能がアクティブになっていることを確認し、Reactアイコンの背景色が赤の場合、アプリは開発モードになっています。 逆に背景色が黒色の場合は、アプリは本番モードになっております。
- Reactコンテキストとはなんですか?
-
ContextAPIは、Reactのバージョン16.3で追加された機能となります。 ReactContextAPIを使用すると、アプリすべてまたは一部、全体で小道具を手動で渡すことなく、コンポーネントツリーを介してデータを渡すことができます。 つまりコンポーネントツリーの深さに関係なく、状態を簡単に子コンポーネントへ共有できるようにします。 ContextAPIを使用すると、データが存在する中央ストアを作成できます(Reduxの場合と同じです)。 ですが、ContextAPIは完全なReduxの代替えではない事にもに注意して下さい。 コンテキストをアプリケーションに統合する場合は、かなり複雑になることを考慮して置いてください。 dev-k.hatenablog.com
- Reactの高次コンポーネントとは何ですか?
-
高次コンポーネント(HOC)は、コンポーネントの再利用性ロジックを含む概念を適用するためにReactで広く使用されている手法となります。 つまりHOCを使用すると、ロジックを書き直すことなく、さまざまなコンポーネント間でロジックを共有できます Reactの高次コンポーネントは、コンポーネントを引数として取り、新しいコンポーネントを返す関数となります。 ReactAPIの一部ではありませんが、Reactの構成上の性質から前面に出てくるパターンです。 使用する際は、引数として別のコンポーネントを取ります。 そして新しいコンポーネントを返し、返されるコンポーネントは、渡したコンポーネントをレンダリングします。 つまりHOCは、関数を引数として受け取るか、returnで関数を返すたびにこのように呼び出される高階関数の概念に由来し、構成されているという事になります。
const higherOrderComponent = WrappedComponent => { class HOC extends React.Component { render() { return <WrappedComponent /> } } return HOC }
呼び出しは下記のようにします。const SimpleHOC = higherOrderComponent(MyComponent);
HOCは、元のコンポーネントをコンテナコンポーネントでラップすることによって構成します。 HOCコンポーネントは、さまざまな機能に使用できこれらの純粋関数は、関数型プログラミングの本質となってます。書くのが慣れると、アプリのメンテナンスやアップグレードが簡単になっていることに気付くはずです。
- Reactのエラー境界とはなんですか?
-
Reactのv16で導入されたエラー境界は、レンダリングフェーズ中で発生するエラーをキャッチする方法を提供します。 開発中にアプリで予期しないエラーが発生することは避けられません 存在しない、深くネストされたプロパティにアクセスしようとしている可能性がありますまたはAPIリクエストの失敗など。 『ReactErrorBoundary』を使用して発生する可能性のあるすべての予期しないエラーを報告しましょう。 react-error-boundaryは、Reactのエラー境界のラッパーであり、開発者がエラー境界を最初から作成せずにコードに実装できるようにします。 子コンポーネントツリーで発生する可能性のあるエラーをキャッチし、それらのエラーをログに記録して、フォールバックUIを表示できるようにするコンポーネントとなります。 使用方法は下記で解説しております。 dev-k.hatenablog.com
- Reactでよく使用するCLIコマンドはなんですか?
-
なるべくCreateReactAppコマンドラインで使用する基本的なコマンドに限定して紹介していきます。 • npxスクリプト
npx create-react-app my-react-app
• npmまたはyarnパッケージコマンドnpm init react-app my-react-app or • yarn init react-app my-react-app
•テンプレート選択create-react-app my-app --template typescript
• React依存関係パッケージのインストール npmまたはyarnのパッケージコマンドnpm install --save react-router-dom or yarn add react-router-dom
• アプリケーションの実行npm start or yarn start
• buildの実行npm run build
• ローカル展開npm install -g server ↓ serve -s build
• テストの実行npm run test or yarn test
関数コンポーネント(フック)に関するよくある質問
- Reactフックとは何ですか?
-
フックはクラスコンポーネントを記述せずに全てのReact機能を使用できます。 つまり関数コンポーネントを介して、Reactの状態とライフサイクル機能をサポートします。 フックを使用するとコンポーネント階層を変更せずにステートフルロジックを再利用できます。 これにより機能的なコンポーネントだけでReactアプリケーション全体を作成できます。 またフックを多くのコンポーネント間またはコミュニティと簡単に共有が可能となっております。
- Reactフックはクラスコンポーネントで機能しますか?
-
いいえ。 残念ながらクラスコンポーネントではフックをサポートしていません。 しかしクラスと関数コンポーネントを1つのツリー内にフックと組み合わせることができます。 コンポーネントがクラスであるか、フックを使用する関数であるかは、そのコンポーネントの実装の詳細となります。 Reactではクラスを削除する予定はありません。 ただし、フックは柔軟性が高くコードの理解が容易であるため開発者はすぐにフックに移行する必要があります。
- Reactフックが導入されたのはなぜですか?
-
フックを導入した理由の1つは、クラスコンポーネント内の『this』キーワードの処理が複雑であるためです。 フック導入以前では同じコードを複数の場所に記述していました。 フックを使用すれば、関数コンポーネントを操作する際にその複雑さを回避できます。 つまりクラス、レンダリングプロップを常に切り替える必要があるため、時には大変な作業になる可能性があります。 そこでReactフックの実装です、関数コンポーネントを使用して切り替えることなく、それらすべてを実行できるようにし、かつコンポーネント階層を変更せずにステートフルロジックを共有できるためでもあります。 最後の理由としては、複数のクラスコンポーネントでは様々なライフサイクルメソッドが散在しており、それらメソッドに依存しています。 その中でも最も使用頻度が高いメソッドは3つです。 •componentDidMount() •componentDidUpdate() •componentWillUnmount() 上記だけでなく、重要なメソッドは他に沢山あります。 これらのライフサイクルメソッドはクラスコンポーネントでのみ使用可能であり、クラスは扱いにくく、理解するのが難しい場合があります。 フックを使用するとクラスを使用せずに『状態』『ライフサイクルメソッド』およびReactの他の機能の使用を実現させました。
- DOM要素にアクセスする方法は?
-
DOM要素にアクセスするにはuseRef()フックを使用するのが最も一般的なケースです。 DOM要素を簡単に見つけその要素の参照を格納できます。
import { useRef, useEffect } from "react"; const MyComponent = () => { const elementRef = useRef(null); useEffect(() => { console.log(elementRef.current); // MyComponent <div> console.log(typeof elementRef.current); // object }, []); return (<div ref={elementRef}>私はelementです。</div>);
useRef()はコンテンツがレンダリングされるまで参照が設定されません。 ですのでフックに渡される初期値は『null』であることに注意してください。 そしてnullは参照によって上書きされます。 要素への参照を割り当てるための、特別な属性である『ref』が使用されます。 要素の幅と高さを取得または、最初にレンダリングされたときに焦点を合わせたりするなど、便利な機能となっています。 dev-k.hatenablog.com
- useState()フックはどのように機能し、また2番目の引数とは何ですか?
-
『useState()』は組み込みのReactフックの1つです。 このフックは、関数コンポーネントに状態値を格納するために使用されるものです。 状態の初期値として引数を受け入れます、2つの要素を持つ配列を返します。 最初の要素では状態の現在の値です。2番目の要素は状態を更新する関数です。
const [stateValue, updateState] = useState(initialStateValue);
import { useState } from "react"; const Counter = () => { const [count, setCount] = useState(0); return ( <div> <button onClick={() => { setCount(count + 1); }} > Count: {count} </button> </div> ); }
上記の場合、初期値である0は最初の要素である『count』に格納されています。 2番目の要素『setCount』では初期値である0を更新する為の関数として使用します。 そしてコンポーネントのボタンがクリックされるたびに、setCount関数が呼ばれカウントが増加致します。
- useState()フックを使用して配列操作するには?
-
まずはReactの配列状態に新しい値を追加する方法です。
const testArray = ['a', 'b', 'c'];
前の配列の値をデフォルトとして、状態を作成できます。import { useState } from "react"; const [myArray, setMyArray] = useState(testArray);
配列を直接追加するには。const [myArray, setMyArray] = useState(['a', 'b', 'c']);
空の配列として状態を作成することもできます。const [myArray, setMyArray] = useState([]);
状態配列への新しい要素の追加(プッシュ)の方法です 通常では、push()を使用し配列に新しい要素を追加します。 しかし状態は不変である為、通常のJSのように単純にプッシュする事はできません。 ReactではuseState()から返されたメソッドを使用して配列を更新する必要があります。 変わりに『setMyArray』で前回のuseStateの呼び出しで返されたメソッドとJavaScriptのspread演算子(…)を使用する必要があります。setMyArray((arr) => [...arr, 'arr.length']);
完全な使用方法の例を下記にありますので、試してみてください。const App = () => { const [myArray, upMyArray] = useState([]); const onClick = () => { upMyArray((arr) => [...arr, 'arr.length']); } return ( <div> <input type="button" onClick={onClick }value="Update" />, <div>{myArray.map(e => <div>{ e }</div> )} </div> </div> ) }
Reactは返された配列を新しい状態として使用し、結果として、Reactコンポーネントの状態に新しい値を追加することができます。
- useState()フックがすぐに更新されないのはなぜですか?
-
クラスコンポーネントのsetState()同様にフックによって提供されるアップデータを使用した状態の更新も非同期であり、すぐには反映されません。 したがって、Reactの状態を更新するプロセスはパフォーマンス上の理由から非同期となっており、変更はすぐに感じられません。 更新が要求された場合、更新がすぐに行われるという保証はありません。
Reactでは状態が更新されるたびに、更新されるコンポーネントが再レンダリングされます。 再レンダリングはコストのかかる操作であるため、状態の更新を同期的に行うと、読み込み時間が長くなったり、アプリケーションがクラッシュしたりするなどの深刻なパフォーマンスの問題が発生する可能性があります。
ですが状態の更新をバッチ処理することで、Reactは不要な再レンダリングを回避し、全体的なパフォーマンス向上が実現可能です。
- useEffect()フックの目的は何ですか?
-
useEffectフックを使用すると、関数コンポーネントで副作用を実行できます。 副作用の例は、データのフェッチリクエスト、DOMの直接更新、タイマー関数などがあり多くの問題の解決策となります。 useEffectフックを使用することは、コンポーネントのライフサイクルを理解することにも直結します。 クラスベースのコンポーネントで使用可能なライフサイクル機能を関数コンポーネントで状態やその他のいくつかの機能を使用できるようにする特別なフックです。 また、複数のuseEffectフックを使用してコードのロジックを分割することもできます。
- useEffect()フックで1回だけ呼び出す方法は?
-
コンポーネントがマウントされたときにコールバックを1回だけフックさせるように実行するには、空の配列をuseEffectの2番目の引数に渡す必要があります。
const App = () => { useEffect(() => { console.log('マウントされています'); return () => console.log('unmounting...'); },[]) //空の配列を追加する return ( <div> </div> ) }
空の配列を2番目の引数に渡すだけです、useEffectコールバックは1回だけ実行されます。
- コンポーネントがアンマウントされた時にコードを実行するのは可能ですか?
-
はい可能です。 useEffectフックを使用します。 コンポーネントがアンマウントされたときにコードを実行するには、フックで関数を返すだけで実現可能です。
useEffect(() => { console.log("mounted"); return () => { console.log("unmounted"); }; }, []);
アンマウントでのみコードを実行する場合は、空の依存関係配列を使用する必要があります。import {useRef, useEffect, useState} from 'react'; const App = () => { const [mounted, setMounted] = useState(true); return ( <div> <button onClick={() => setMounted(current => !current)}> click me </button> <hr /> {mounted && <Child />} </div> ) } function Child() { const ref = useRef(null); useEffect(() => { const handleClick = e => { console.log('Button clicked'); }; const element = ref.current; element.addEventListener('click', handleClick); //コンポーネントがアンマウントされたときに実行される関数 return () => { console.log('unmounted'); element.removeEventListener('click', handleClick); }; }, []); return ( <div> <button ref={ref}>Click</button> </div> ); }
アンマウント時に実行されるのが確認できます。 これは主にクリーンアップの目的で使用できます。
- カスタムフックとは何ですか?何の為に使用しますか?
-
カスタムフックは、一部のコンポーネントロジックを再利用が可能な関数として作成します。 つまりカスタムフックを作成する主な理由は、コードの再利用性の為となり、コンポーネントを可能な限りシンプルに保ち、テスト可能なロジックをカスタムフック関数で分離し、コンポーネント間の共有ロジックを再利用可能に致します。 他の様々なフックを呼び出すことができるJavaScript関数です。 接頭辞として『use』が付いています。 組み込みのフックを使用し、フックのルールにも準拠しているため、これは任意の数の引数を受け入れ、コンポーネントで使用できる値とメソッドを公開できます。
const [count, setCount] = useCustomHook()
dev-k.hatenablog.com
- ステートフルロジックとはなんですか?
-
よく『コンポーネント間でステートフルロジックを共有する』や『ステートフルなコンポーネント』または『ステートレスなコンポーネント』など聞くかと思います。 このステートフルロジックは、本来のステートとは異なります。 それはコンポーネントのローカル状態を保持または管理し使用した場合は、『ステートフルコンポーネント』となります。 対象的に『ステートレスコンポーネント』では状態がありません、そして再利用はできません。つまり状態を保持または管理しないという事になります。 Reactの最も一般的なプログラミングパターンの1つは、ステートフルな親コンポーネントを使用して独自の状態を維持し、それを1つ以上のステートレスな子コンポーネントに小道具として渡します。 現在Reactではカスタムフックがございます。 これはJavaScriptの関数間でロジックを共有したい場合、それを別の関数に分離します。 カスタムフックを使う場所ごとに、内部の state や副作用は完全に分離され、複数のコンポーネント間でステートフルロジックを共有することになります。 つまりは状態を変更させるために行う為のものです。 カスタムフック関数は共通のコードを別の関数に分離しただけということだけです。
- 関数コンポーネントで複数の状態を使用する事は可能ですか?
-
はい、可能です。 関数コンポーネント内から複数の状態変数を使用および更新できます。
//複数の状態変数を宣言します const App = () => { const [age, setAge] = useState(19) const [siblingsNum, setSiblingsNum] = useState(10) const [count 、setCount] = useState(0); }
1つの関数内で複数の状態を宣言しています。
- Reactフックでフォーム作成はどのように作成しますか?
-
フォームの作成は、どのWebアプリケーション開発でも非常に一般的です。 HTMLでは、input、textarea、selectなどのフォーム要素は通常は独自の状態を維持し、ユーザー入力に基づいて更新します。 HTMLの場合と同様に、Reactはフォームを使用して、ユーザーがWebページを操作できるようにする事も可能です、それは制御されていないコンポーネントまたは非制御コンポーネントとなります。 ですが、これは一般的にReactで実現したいことではありません。 基本的にはReactにフォームを制御をさせる方法です、それが制御されたコンポーネントとなります。 データが制御されたコンポーネントによって処理される場合、すべてのデータはコンポーネント状態で保持されます。 useState()フックを使用し、入力を管理します。 onChange属性にイベントハンドラーを追加することで、変更を制御が可能となります。
const MyForm = () => { const [name, setName] = useState(""); return ( <form> <label>your name: <input type="text" value={name} onChange={(e) => setName(e.target.value)} /> </label> </form> ) }
フォームの送信は、onSubmit属性にイベントハンドラーを追加することで、送信アクションを制御する事が可能となります。const handleSubmit = (event) => { event.preventDefault(); alert(`名前は?: ${name}`) } return ( <form> <input type="submit" /> </form> )
独自でフォームを作成した場合、管理が大変かと思います。 その場合は、React Hook Form ライブラリまたは他のライブラリを検討下さい。 またNetlify Formsフォームを活用すれば、サーバー側のコーディングを行う必要がなく、開発の時間を節約できます。
- フックの計算をメモ化するにはどうすればいいですか?
-
計算を記憶するためには『useMemo()』フックを使用します。 このメモ化手法を使用するとコンポーネントのパフォーマンスを向上させることができます。 以前の計算を記憶することで、複数のスレッド間で計算をキャッシュできます。 useMemo()は、2つの引数(結果と配列)を受け入れる組み込みのReactフックです。
const memoizedValue = useMemo(compute, dependencies);
初回レンダリング中にuseMemoを呼び出してから、計算結果を記憶し、その後コンポーネントに返します。 抑えておく点は、再レンダリング中に依存関係が変更された場合はその変更された新しい値を記憶し、それを返します。 つまり依存関係の1つが変更された場合にのみ、メモ化された値を再計算します。const memoizedValue = useMemo( () => { return expensiveValue(a、b) }, [a, b]); //依存関係
計算コールバックが小道具または状態値を使用する場合に限り、これらの値を依存関係として必ず示してください。 逆に依存関係が最後の値から変更されていない場合ではuseMemoはそれを再度呼び出すことをスキップし、メソッドが返した最後の値を再利用します。
- フックでpropsを渡すにはどうすればいいですか?
-
まずは親コンポーネントの作成をします。
const App = () => { const greeting = 'Hello. Welcome.' return ( <div> <Welcome text={greeting}/> </div> ); };
小道具を要素の属性としてtext設定にします。 事前に子コンポーネントの名前は『Welcome』に決めておいたので作成します。const Welcome = (props) => { return <h1>{props.text}</h1>; };
ブラウザには『Hello. Welcome.』と表示されます。 子コンポーネントでログに出力し確認してみましょう。const Welcome = (props) => { const result = props.text; console.log(result) //Hello. Welcome. return <h1>{result}</h1>; };
ブラウザとログ両方で確認がとれたかと思います。 小道具(props)を使用すると、あるコンポーネントからコンポーネントツリーの別のコンポーネントに値を渡すことができます。 また変数宣言をせずに小道具をインラインで渡す事も可能です。 JavaScript文字列の場合では二重引用符または一重引用符内に小道具として渡せます。const App = () => { return ( <div> <Welcome text={"Hello. Welcome."} /> // または<Welcome text="Hello. Welcome." /> </div> ); }; const Welcome = ({ text }) => { return <h1>{text}</h1>; };
JavaScriptオブジェクトで渡す場合は下記の通りです 2つの波括弧があるためややこしいかもしれません。 1つ目はJSX用のオブジェクトです。 2つ目がJavaScriptオブジェクト表記の波括弧となります。const App = () => { return ( <div> <Welcome text={{ greeting: 'Welcome to React' }} /> </div> ); };
これが基本的にReactのコンポーネントからコンポーネントに小道具が渡される方法となります。 小道具はReactアプリケーションのコンポーネント階層で上から下にのみ渡されます、つまり親から子のみです。 Reactの小道具は読み取り専用(不変)であることに注意して下さい。 小道具は親から子へコンポーネントツリーにデータを転送するためだけの手段となります。
- Reactフックを使用する際に従わなければいけないルールはなんですか?
-
フックはJavaScriptの関数ですが、使用する際はフックのルールに厳守しながらコードを書いていく必要があります。 それらルールは下記となります。 •Reactフックはトップレベル(最上位)でのみ呼び出すことができ、ループ、条件、またはネストされた関数の内部で呼び出すことはできません、つまりフックが呼び出される順序に依存している事になりますのでご注意下さい。 •フックはReact関数またはカスタムフックでのみ呼び出すことができ、通常のJavaScript関数でフックを使用することはありません、またクラスコンポーネントではフックをサポートされておりません。 ですがクラスと関数コンポーネントを1つのツリー内のフックとして組み合わせは可能です。 ESLintでこれらフックルールの確認が可能となります。 dev-k.hatenablog.com
- Reactのどのバージョンからフックが使用可能ですか?
-
Reactフックはバージョン16.8.0でReactに追加されました。 ですのでフックを有効にする場合は全てのReactパッケージが16.8.0以降であれば、使用可能となります。 ReactNativeではバージョン0.59からフックをサポートしております。
- 関数から状態の初期化は可能ですか?
-
はい、可能です。 Reactで状態を初期化する方法は様々ありますが、関数から、初期状態でパフォーマンス面でコストのかかる操作が必要な場合は、useState()フックを使用しオプションの引数を初期状態値として取り、現在の状態とそれを更新する関数を返します。
const App = () => { const [counter, setCounter] = useState(1); const incrNum = () => { setCounter(counter + 3); } return ( <div className="container"> <h1>Increment: 3</h1> <div className="counter-box"> <span>{ counter }</span> <button onClick={incrNum}>+ 3</button> </div> </div> ) }
メソッドであるincrNumは、counterの値をインクリメントすることによって現在の値である3の状態を更新するとコンポーネントの再レンダリングが発生します。 状態の遅延初期化をしたい場合 Reactがコンポーネントを再レンダリングするたびにuseState()が実行され、初期状態がプリミティブ値(数値、文字列など)の場合、上記のような作成および状態の初期化した際のパフォーマンスの問題はありません。 ですが初期状態でパフォーマンス面でコストのかかる操作が必要な場合は、useState()フックで引数として関数を渡して、状態を遅延的に初期化も可能です、初期値は初回のレンダリングで1回だけ必要です。 下記はボタンを数回クリックした際、遅延が経過すると1ずつ数が2秒遅れで増えていきます。const App = () => { const [count, setCount] = useState(0); const handleClickAsync = () => { setTimeout(function delay() { setCount(count => count + 1); }, 2000); } return ( <div> {count} <button onClick={handleClickAsync}>Increase async</button> </div> ); }
- useEffectとuseLayoutEffectフックの違いはなんですか?
-
これらフックはほとんど同じように動作します。 useEffectフックとuseLayoutEffectフックの違いは全ては、それらの呼び出しのタイミングにあります。 主な違いは、useLayoutEffectフックは同期後に実行されます。 つまりuseEffectフックが実行される前に実行されます。 使用する際は、DOMを直接変更する必要がある場合にのみ使用してください。 useEffectフックはレンダリングされた要素が画面に描画された後に、非同期として実行されます。 非同期なのか同期なのかです。 useLayoutEffectフックは同期的であるため、使用する場合は注意が必要となります。 パフォーマンスが低下する可能性があります、それはこのメソッドの実行が終了するまでUIは更新されないためです。 詳しくは下記でも解説しております。 dev-k.hatenablog.com
クラスコンポーネントでよくある質問
- setState()とはなんですか?
-
状態のあるコンポーネントはステートフルコンポーネントと呼ばれます。 Reactでは、各コンポーネントに状態を設定できます。 UIは状態に基づいてレンダリングされ、状態が変わるとUIも変わります。 Reactクラスコンポーネントの状態オブジェクトを変更するには、setState()を使用します。 setState()関数は、新しい状態と前の状態の間で浅いマージ(結合)を実行します。 状態は、イベントハンドラーやサーバーの応答などの変更に応じて更新できます。 つまり常にsetState()メソッド を使用して状態オブジェクトを変更します。
class App extends React.Component { constructor(props) { super(props); this.state = { name: "Taro", age: 30, city: "Tokyo", favoriteColor: "White" }; } changeClick = () => { this.setState({ favoriteColor: "Blue" }); } render() { return ( <div> <h1>My name is.{this.state.name}</h1> <p> City: {this.state.city}. age: {this.state.age}. Favorite color: {this.state.favoriteColor} </p> <button type="button" onClick={this.changeClick} >Change</button> </div> ); } }
setState()はキーと値のペアを持つオブジェクトです。
- setState()は非同期ですか?
-
はい、setState()の動作は非同期であり、パフォーマンスを向上させるためにバッチ処理されています。 これは同期させるとブラウザが応答しなくなる可能性があるので、状態を変更して再レンダリングを引き起こすためです。 setState()メソッドが非同期なので、コードの問題をデバッグするのが難しいという事を忘れないようにしておいて下さい。
- setState()に渡される2番目の引数の使用方法と目的は?
-
2番目の引数はsetState()が終了し、機能のパーツが再レンダリングされたときに呼び出されるコールバック作業です。 つまり、setStateへの2番目の引数として渡すものはすべてsetState関数が更新された後に実行されます。
class App extends React.Component { constructor(props) { super(props); this.state = { counter: 0 }; } changeClick = () => { this.setState({ counter: 1 }, () => console.log(this.state.counter + 5)); } render() { return ( <div> <p> {this.state.counter} </p> <button type="button" onClick={this.changeClick} >Change</button> </div> ); } }
ボタンクリックでブラウザ上で0から1に更新されます、クリック後にコンソールで確認して下さい。 『6』と出力されてるかと思います。 これはコールバック関数であるオプションの2番目のパラメーターであるsetStateを渡すことができます。 ですが、setState()は非同期であるため、コールバック関数はすべてのアクションに使用されます。 このコールバック関数ではなく、ライフサイクルメソッドを使用することをお勧めします。
- クラスのsuper()にpropsが渡されるのはなぜですか?
-
Reactでクラスコンポーネントを作成するとき、コンポーネントのコンストラクターでsuperを呼び出し、props(小道具)を渡すことがよくあります。
class App extends React.Component { constructor(props) { super(props); this.state = { isOn: true }; } // ... }
ですが、我々は本当にこれを行う必要性はあるのか? どういうわけか、super()の引数なしで呼び出した場合でも他のメソッドでpropsにアクセスできます。 しかしsuperに小道具を渡す事はReactドキュメントは強く推奨しております。 superは親クラスのコンポーネントを指します。 重要なのは、親コンストラクターを呼び出すまで、コンストラクターでthisを使用できないことです。 コンストラクター内でthis.propsを使用する場合は、superで渡す必要があります。 そうでない場合は、superに渡すかどうかに関係なく、this.propsが内部で利用可能であることがわかるため、小道具をsuperに渡さなくてもかまいません。 つまり、なぜ渡されるのかはthis.propsにアクセスしたい場合は、メソッドconstructor()内でsuper()に小道具を渡す必要があるという事です。
- クラスのextendsとはなんですか?
-
継承を使用してサブクラスを定義できます。 サブクラスは、既存のクラスを『拡張』するクラスで既存のクラスの属性とメソッドに加えて、さらに多くのものがあります。 つまりAppクラスからメソッドを継承しApp2という名前のクラスを生成します。
class App extends React.Component { constructor(props) { super(props); this.state = { }; } // ... } class App2 { constructor(test) { // ... } }
extendsキーワードを使用し、(親)とは別の子クラスを作成するために使用されます。 これはスーパークラスであり、そのサブクラスの1つであるとも言えます。 子クラスは、別のクラスからすべてのメソッドを継承します。 継承はコードの再利用に役立ち、新しいクラスを作成するときに、既存のクラスのプロパティとメソッドを再利用します。
- constructor(props)の役割と目的は?
-
クラスのコンストラクターは、そのクラスのオブジェクトが作成されたときに自動的に呼び出されるメソッドです。 Reactでのコンストラクターはコンポーネントの作成中およびマウント前に呼び出されます。 Reactコンポーネントのコンストラクターを実装する場合は、他のsuper(props)の前にメソッドを呼び出します。 そうでなければ、this.propsコンストラクターで未定義になりバグが発生します。
constructor(props) { super(props); console.log(this.props); }
Reactでは、コンストラクターは主に2つの目的で使用されます。 • Reactのコンストラクターはthis.stateのオブジェクトに値を割り当てコンポーネントの状態を初期化するために使用されます。 • コンポーネントで発生するイベントハンドラーメソッドをバインドするために使用されます。 ですのでイベントハンドラーをバインドしていない場合は、コンストラクターをわざわざ定義する必要はまったくございません。
- render()の役割と目的は?
-
React.jsのレンダリング関数は、コンポーネントに表示するHTMLを返すために使用されます。 renderメソッド内で記述された、JSXコードはDOMに更新される前にHTMLに変換されます。 すべてのRender関数にはreturnが含まれます。 レンダリングされる場所は、CRAを使用してる方であれば、Reactプロジェクトのルートディレクトリに『public』という名前のフォルダがあります。 このフォルダ内に『index.html』ファイルがあります。 そのファイル内に記述されている、idの『root』ここがReactアプリケーションがレンダリングされる場所となります。
- クラスメソッドをクラスインスタンスにthisをバインドする必要があるのは何故ですか?
-
Reactクラスコンポーネントは基本的にJavaScriptのクラスであり、クラスがクラスに拡張された場合、Reactのすべての機能が割り当てられます。 クラスで宣言された関数はthisオブジェクトに追加されます。 Reactにとっての『this』はReactコンポーネントクラスでは、propsやstateなどのクラス属性を参照するメソッドを定義します。 this経由でアクセスすると、エラーが発生します。 なぜエラーなのか、それはReactクラスコンポーネントを参照する代わりに、Windowオブジェクトを参照したということです メソッドがthis.stateおよびthis.propsにアクセス可能にするには、コンポーネントのthisをコンテキストメソッドにバインドbind()する必要があります。 通常の関数には独自のオブジェクトがあるため、関数のthis内部がオブジェクトを参照するためです。 thisをクラスメソッドにバインドする事により、小道具と状態にアクセス可能です。
- thisをバインドする方法は?
-
Reactイベントリスナーでコンポーネントを作成した場合下記のコードを使用すると、目的の操作を実行できず、バインドが必要になります。
<button type="button" onClick={this.myHandler}>Hello</button>
この問題を解決するためのアプローチの1つは、ES6で導入されたアロー関数の使用法です。 これらの関数には、デフォルトで。thisへのバインドがあります。class App extends React.Component{ myHandler = () => { console.log(this); } render() { return( <button type="button" onClick={this.myHandler}>Hello</button> ) } }
または、コンストラクター関数内で明示的にバインドしてあげます。class App extends React.Component { constructor(props) { super(props); this.state = { }; this.handleClick = this.handleClick.bind(this); } //{…} }
他にバインド方法はございます、下記で解説しております。 dev-k.hatenablog.com
- Reactのライフサイクルの概念とメソッドとは?
-
これは、概念の1つとなりますが決して複雑ではありません。 Reactのすべてのコンポーネントは、イベントのライフサイクルを通過します。 つまり各コンポーネントは、マウント、更新、アンマウントの3つのフェーズを経ます。 私は例としてそれらを誕生、成長、そして死のサイクルを経ていると考える例えは非常に分かりやすいと思っています。 コンポーネントは、初めてレンダリングするときに『マウント』されます。 そして2回目以降のレンダリングでコンポーネントはレンダリングされる度に『更新』されます。 その後コンポーネントがDOMから削除されたときが『アンマウント』コンポーネントの破棄となります。 これらマウント、更新、アンマウントの3つのフェーズが繰り返し行われます。 前述した例えで、誕生→成長→死、人間の人生と同じサイクルです。 コンポーネントがマウントされ、段階を踏んでアクションを実行するための特定のライフサイクルメソッドを提供します。 そのライフサイクルメソッドは下記となります。 一般的によく使用されるメソッド • constructor() コンポーネントがDOMにマウントされる前に、コンストラクターメソッドが呼び出され、ほとんどがコンストラクターメソッド内で状態を初期化し、イベントハンドラーメソッドをバインドします。 • render() 要素をDOMにレンダリングする場合、例えばJSXを返す場合にrender()メソッドを記述します。 • componentDidMount() render()が呼び出された後に、コンポーネントがDOMにマウントされ、componentDidMount ()メソッドが呼び出されます。 この関数は、コンポーネントがDOMにマウントされた直後に呼び出され、コンポーネントツリーからDOMノードを取得します。 componentDidMount()ではsetState()を使用できます。 ここでsetState()を呼び出す と、状態が更新されて別のレンダリングが発生しますが、ブラウザがUIを更新する前に発生します。 ユーザーが二重レンダリングでUIの更新を表示しないようにするためです。 注意点は、パフォーマンスの問題が発生する可能性があるため、モーダル実装およびその位置に依存するDOMノードを測定し参照する必要がある場合などのケースで使用されます。 • componentDidUpdate() このライフサイクルメソッドは、更新が行われるとすぐに呼び出されます。 このライフサイクルでsetState()を呼び出すことができますが、状態または前の状態からの小道具の変更を確認するために、それらを条件でラップする必要があることに注意してください。 setState()を誤って使用した場合、無限ループが発生する可能性があります。 • componentWillUnmount() コンポーネントのアンマウントフェーズ中に呼び出されます。 このライフサイクルメソッドは、コンポーネントがマウント解除されて破棄される直前に呼び出されます。 これは主に、タイマーのクリア、ネットワークリクエスト(API)のキャンセル、またはストレージ内のキャッシュのクリアなどで必要なメソッドとなります。 ※このコンポーネントは再レンダリングされないため、このライフサイクルメソッド中にsetState()を呼び出すことはできません。 下記は使用頻度は控えめなメソッド • shouldComponentUpdate() このライフサイクルは、Reactに状態や小道具の変更をレンダリングさせたくない場合に使用される事があります。 shouldComponentUpdate()メソッドは、コンポーネントが状態とプロパティの変更の影響を受けていないかどうかをReactに通知するために使用されます。 つまりパフォーマンスの最適化対策となります。 • staticgetDerivedStateFromProps staticgetDerivedStateFromPropsは、 React 17以降の比較的に新しいReactライフサイクルメソッドであり、『componentWillReceiveProps』を置き換えるように設計されています。 これは、 render()メソッドを呼び出す直前に呼び出されます。 『this』にアクセスできない静的メソッドです。 getDerivedStateFromPropsは、コンポーネントが使用する小道具が変更され、古い小道具を保存していた以前の状態とは異なるかどうかを確認するために使用されます。 thisキーワードにアクセスにできないという事は、this.setState()呼び出す事ができなくなります。 そうなると状態の更新もできません。 更新を行うには、新しい状態値を持つオブジェクトを返すだけとなります。
static getDerivedStateFromProps = (nextProps, prevState) => { if(nextProps.itemName === prevState.itemName) { return null } return { itemName: nextProps.itemName } }
何も変更されていない場合は、『null』を返す必要があります。 • getSnapshotBeforeUpdate getSnapshotBeforeUpdate()は、最近Reactで導入されたもう1つの比較的に新しいライフサイクルメソッドです。 getSnapshotBeforeUpdateライフサイクルメソッドは、DOMが更新された後、状態の以前の値を保存します。メソッドの直後に呼び出されます。 これは開発者が、DOMが変更される前にDOMに関する情報を取得できます。 ほとんどの場合、このライフサイクルに到達することはめったにありません、使用する事もほとんどありません。 それぞれ必要に応じて学習下さい。
- setState()を使用せずにコンポーネントを強制的に再レンダリングする事は可能ですか?
-
はい、可能です。 クラスコンポーネントでは、『forceupdate』を呼び出して強制的に再レンダリングするオプションがあります。 ただし、一般的には強制更新の使用を回避するように努める必要があるという事は忘れないで下さい。 この方法はお勧めできません、新しいレンダリングを作成するには、常に小道具と状態を使用する必要があります。 ですがその方法を紹介します。
class App extends React.Component { constructor(props) { super(props); this.state = { counter: 0 }; this.changeClick = this.changeClick.bind(this) } changeClick = () => { //強制的に再レンダリング this.forceUpdate() this.state.counter = + 1 } render() { return ( <div> <p> counter: {this.state.counter}. </p> <button type="button" onClick={this.changeClick} >Change</button> </div> ); } }
setState()を使用せず、ボタンをクリックするとReactのforceUpdate()メソッドで強制的に0から1へ再レンダリングさせている事が分かるかと思います。
- Reactクラスでのデータ取得と状態の更新をするには?
-
サーバーからフェッチされたデータを使用してクラスコンポーネント内のコンポーネントの状態を更新する方法を解説します。 オブジェクト内のusersは初期状態として空の配列に設定しときます。
class App extends React.Component { state = { users: [] } render() { return ( <ul> {this.state.users.map((user) => ( <li key={user.id}>{user.title}</li> ))} </ul> ) } }
ライフサイクルメソッドのcomponentDidMount()を使用します。 サーバーにデータを要求するのに最適です。 状態を設定すると2回目のレンダリングが発生しますが、ブラウザが画面を更新する前に発生します。componentDidMount() { fetch('https://some-api.com/harry-potter') .then((response) => response.json()) .then(usersList => { this.setState({ users: usersList }); }); }
componentDidMount()が正常に呼び出された後にsetState()が呼び出され、新しいレンダリングがトリガーされ、リストとして表示されます。class App extends React.Component { state = { users: [] } componentDidMount() { fetch('https://jsonplaceholder.typicode.com/posts') .then((response) => response.json()) .then((usersList) => { this.setState({ users: usersList }); }); } render() { return ( <ul> {this.state.users.map((user) => ( <li key={user.id}>{user.title}</li> ))} </ul> ) } }
ではイベント状態の更新をこのまま解説します。
ボタンをクリックしたときにユーザーリストを取得したい場合は、下記のように新しいメソッドで定義しAPIを呼び出すことが可能です。class App extends React.Component { state = { users: [] } fetchUsers = () => { //新しくメソッドを定義 fetch('https://jsonplaceholder.typicode.com/posts') .then((response) => response.json()) .then((usersList) => { this.setState({ users: usersList }); }); } render() { return ( <div> <button onClick={this.fetchUsers}>Load List</button> {this.state.users.length > 0 && ( <ul> {this.state.users.map((user) => ( <li key={user.id}>{user.title}</li> ))} </ul> )} </div> ) } }
ボタンをクリックすると、前述にcomponentDidMount()メソッドで行ったのと同じフェッチ要求を行うボタンを追加しました。 そして、ゼロを超えた場合のみにリストをレンダリングさせる条件付きとなります。
.qa-list dl { position: relative; margin: 0; padding: 28px 80px 28px 30px; cursor: pointer; border-bottom: 1px solid #000; }
.qa-list dl::before { position: absolute; top: 35px; right: 35px; display: block; width: 7px; height: 7px; margin: auto; content: ''; transform: rotate(135deg); border-top: 2px solid #000; border-right: 2px solid #000;
} .qa-list .open::before { transform: rotate(-45deg); } .qa-list dl dt { position: relative; margin: 0; padding: 0 0 0 50px; font-weight: bold; font-size: 20px; top: 20px; color: #4459b6; background: #DDD;
} .qa-list dl dt::before { font-size: 22px; line-height: 1; position: absolute; top: 5px; left: 0; display: block; content: 'Q'; color: #3285bf; padding: 0 0 0 10px; } .qa-list dl dd::before { font-size: 22px; line-height: 1; position: absolute; top: 0; left: 10px; display: block; content: 'A.'; font-weight: bold; color: #3285bf;
} .qa-list dl dd { position: relative; display: none; height: auto; margin: 20px 0 0; padding: 0 0 0 40px; border-bottom: 1px solid #DDD; border-left: 1px solid #DDD; border-right: 1px solid #DDD;
}
.entry-content pre { right: 15px; }
.qa-list dl dd p { margin: 30px 0 0; position: relative; top: 20px; right: 15px; }
.qa-list dl dd p::before {
content: "\A" ;
white-space: pre ;
}
.qa-list dl dd p:first-child{ margin-top: 0;
}
.entry-content pre { right: 15px; }
}
@media screen and (max-width: 767px) { .qa-list dl { position: relative; padding: 15px 40px 15px 10px; } .qa-list dl::before { top: 20px; right: 20px; width: 7px; height: 7px; } .qa-list dl dt { padding: 0 0 0 30px; font-size: 14px; color: #4459b6; background: #DDD; } .qa-list dl dt::before { font-size: 14px; top: 5px; left: 5px; content: 'Q';
padding: 0 0 0 10px;
}
.qa-list dl dd::before { font-size: 14px; top: 0; left: 10px; content: 'A.'; } .qa-list dl dd { margin: 10px 0 0; padding: 0 0 0 30px; font-size: 14px; border-bottom: 1px solid #DDD; border-left: 1px solid #DDD; border-right: 1px solid #DDD;
} .qa-list dl dd p { margin: 30px 0 0;
position: relative; top: 15px; right: 15px;
} .qa-list dl dd p:first-child{ margin-top: 0;
}
.entry-content pre { right: 15px; } }
最後に
※ReactのQ&Aはここで一旦、区切らせて頂きます、ご了承下さい。。
この記事は随時更新していきます
Reactに関するよくある質問と、それらに対する簡単な回答をすべて含めるように最善を尽くしました。
さらにReact関連の質問がある場合は、直接お問い合わせいただくか、またはコメントからお願い致します。