プログラミング初心者のための入門ブログエンジニアが未来を切り開く。Propsの渡し方と定義この広告は、90日以上更新していないブログに表示しています。(CRA)を利用して簡単に始められる手順とともに解説します。TypeScriptを使用した独自のReact関数コンポーネントでのPropsの定義方法も紹介します。前提として、あなたがNode.jsを既にインストールしていることを仮定しています。このチュートリアルはTypeScriptの基本的な知識があることも前提としています。ReactとTypeScriptの組み合わせについて学ぶことで、より堅牢なアプリケーションを開発するためのツールとしての利用価値を高めることができます。この記事を参考にして、ReactとTypeScriptの基本をマスターしましょう。props型エラーの検証React.FCとReact.VFCについて最後にTypeScriptとReactの利点Reactアプリケーションを構築するための新しい方法として、TypeScriptが広く採用されています。TypeScriptはJavaScriptのスーパーセットであり、型付き構文をサポートしています。コンパイルすることで、ブラウザで実行できるプレーンなJavaScriptに変換されます。TypeScriptは読みやすさと型チェックの恩恵により、フロントエンドWeb開発でますます人気が高まっています。静的型システムは問題を早期に発見するために役立ちます。必要なPropsを提供していない場合、TypeScriptコンパイラはこれを検出して報告します。Codeを使用する場合は、赤い波線でそれを指摘してくれます。TypeScriptとReactは完璧に相性が良く、両方を組み合わせることでアプリケーション開発の生産性を大幅に向上させることができます。クリーンなコードでバグを減らし、よりシンプルなドキュメントを作成することができます。開発者がコードを保守しやすくなり、コンポーネント間で渡されるプロパティとデータ型をチェックすることでバグを防止し、実装の意図を明確にすることができます。大規模なReactプロジェクトにとって、TypeScriptは価値のあるオプションであることがわかります。静的型チェックは、プロジェクトの拡大に伴い、開発者が迅速かつ正確に修正できるようにしてくれます。TypeScriptを利用することで、Reactアプリケーションの品質と保守性を向上させることができます。CRAのインストールCreate-React-App(CRA)は、コマンドライン(CLI)ツールで、WebpackやBabelなどに気を使うことなく、デフォルトとゼロの構成で新しいReactアプリを簡単に作成し、開発を開始できます。下記のコマンドを使用して、グローバルにインストールすることができます。create-react-appTypeScriptは次のステップで、npxを使用してインストールが可能です。プログラムを開発する際におすすめのエディタはVSCodeです。軽量で高速であり、必要なすべての機能を提供してくれます。SublimeText、WebStorm、Atomなどの他のエディタを使用したい場合は、自由に選択することができます。この記事ではエディタの選択は重要ではありません。typescriptオプションを追加します。下記のコマンドを実行すると、TypeScriptを使用した新しいReactアプリケーションが作成されます。typescriptnpxコマンドは、CLIコマンドやレジストリにホストされている実行ファイルを実行するために使用されます。これにより、グローバルインストールは必要ありません。プロジェクトが作成されると、プロジェクトディレクトリに移動して任意のコードエディタで開くことができます。プロジェクトファイル構成は、下記のようになります。tsconfig.jsontsconfig.jsontsconfig.jsonファイルは、TypeScriptプロジェクトのコンパイラ設定とファイルを示す設定ファイルであり、JavaScriptプロジェクトのpackage.jsonと同様の役割を果たします。]}CRAによって生成されたtsconfig.jsonは、TypeScriptのコンパイラが使用する設定を含んでいます。"es5"は、コードをどのECMAScriptバージョンにコンパイルするかを指定するオプションです。5にコンパイルされます。"esnext"]は、コードがどのライブラリを使用するかを示すオプションです。ここでは、DOMとDOMのイテレータ(配列)を使用することを指定しています。"esnext"を含めることで、最新のJavaScript機能を使用できるようになります。"react-jsx"は、JSXを使用してReactコンポーネントを記述するための設定です。このオプションは、Reactが提供するReact.createElement()を呼び出す代わりに、JSXシンタックスを使用してコンポーネントを記述することを可能にします。["src"]は、TypeScriptコンパイラに含めるファイルを指定するオプションです。ここでは、srcフォルダー内のすべてのファイルを含めるように指定されています。これらのオプションは、TypeScriptコンパイル時に重要な役割を果たします。設定ファイルを変更することで、TypeScriptプロジェクトのコンパイル設定をカスタマイズすることができます。以上が、CRAでTypeScriptを使用する場合の基本的な設定とファイル構成についての解説です。JSXには.tsxファイルを使用TypeScriptを使用してReactを開発する場合、通常のReactアプリの作成方法にいくつかの変更が必要です。.ts拡張子ファイルに加えて、.tsxという新しいファイル拡張子があります。この拡張子は、JSX構文を含むReactコンポーネントファイルを作成する場合に使用します。TypeScriptは、JSXを直接JavaScriptにコンパイルできるため、TypeScriptを使用することでReactアプリケーションをより型安全に、かつコードの品質を高めることができます。TypeScriptを使用することで、パッケージをインストールする必要がなくなるため、開発プロセスがスピードアップすることもあります。BuildなどのJavaScriptバンドラーは、.tsxファイルに対して特別なプラグインを実行することができ、Jestのようなテストランナーは.tsxファイルのテスト環境を実行することができます。.tsxファイル拡張子のサポートにより、コードエディターが新しい言語機能をサポートすることができます。.tsファイル拡張子では、JSX構文や要素の使用を必要としない関数、クラス、レデューサーなどを作成する場合に使用されます。.tsxファイル拡張子は、Reactコンポーネントを作成し、JSX要素および構文を使用する場合に使用されます。PropsとStateにTypeScriptを使用する場合、学習コストがかかるかもしれませんが、一度理解するとReactのデフォルトの方法よりもはるかに強力であることがわかるでしょう。TypeScriptコンポーネント作成まず、Reactアプリケーションの初期ファイルであるCRAデフォルトのApp.tsxファイルを開きます。このファイルには、Reactアプリケーションのルートコンポーネントが含まれています。最初に表示されるロゴやCSS、およびimgタグやaタグは必要ないので、それらを削除して、下記のように簡略化できます。App;それでは、このまま、関数コンポーネントを作成していきましょう。Propsという機能の流れを掴んでいきます。下記の例では、Appコンポーネントが親として、Childコンポーネントが子の関数コンポーネントとなります。userというオブジェクトと、Numを作る関数、そして2つの変数の値を宣言しています。親コンポーネントで、子コンポーネントに渡すPropsを設定し、それをChildコンポーネントに渡しています。)}子の関数コンポーネントは、最初の引数としてPropsをオブジェクトとして受け取ります。親コンポーネントで設定された各属性は、子コンポーネントのPropsの名前となります。一般的な方法では、Propsを分解して取り出すことができます。下記の例では、Propsの各プロパティを分解して、それぞれを変数に割り当てています。CodePen.このように、受け取ったPropsオブジェクトから必要な値を分解して取り出すことで、コードの可読性が向上します。Propsにはデフォルト値を設定することもできます。これは、Propsが渡されなかった場合にその値が使用されるため、コンポーネントの使用時に必須の値であるかどうかを明示することができます。Content"、userには空のオブジェクト、numには空の関数が使用されるように設定しています。以上のように、Propsを適切に扱うことで、Reactコンポーネントの再利用性と保守性を高めることができます。Propsの渡し方ReactでTypeScriptを使用して関数コンポーネントを作成する際には、Propsの型チェックを行うことが推奨されます。親コンポーネントは下記となります。);}MyMessageという子の関数コンポーネントを作成します。TypeScript.</h2></div>;}全てのPropsに対して、オブジェクトとして型を定義をしなければいけません。Propsの型を定義する方法はいくつかあります。インラインで型を定義する方法があります。下記のように、Propsをオブジェクトとして定義し、関数の引数として渡します。CodePen.次に、Propsオブジェクトで型を定義する方法があります。下記のように、Propsオブジェクトを引数として渡します。CodePen.また、interfaceを使用して、Propsの型を定義する方法があります。下記のように、Propsの型をinterfaceとして定義し、関数の引数として渡します。</h2></div>;}子コンポーネントには、messageというプロパティが必要であり、その値は文字列である必要があります。親コンポーネントからPropsを渡す場合、下記のようにmessageプロパティに文字列の値を渡すことができます。CodePen.同様に、下記の例では、3つのPropsを持つコンポーネントに型注釈を付けています。CodePen.UserPropsは、name、age、countryの3つのプロパティを持つオブジェクトを表しています。UserDataコンポーネントは、この3つのプロパティをPropsとして受け取り、それらを表示します。親コンポーネントでは、UserDataコンポーネントにPropsとしてオブジェクトを渡す際に、スプレッド構文(...)を使用してオブジェクトのプロパティを展開しています。Propsの型を正確に定義することで、コンポーネント間での値の受け渡しを安全に行うことができます。TypeScriptを使用することで、開発時のデバッグが容易になり、バグを防ぐことができます。alias)は、TypeScriptで型を再利用するために使用されます。interfaceを使うこともできますが、一貫性と明確性を保つために、型エイリアスを使用することが推奨されます。Reactアプリケーションで、特定のコンポーネントが受け取るPropsを定義する必要がある場合、型エイリアスではなくinterfaceを使用することが理想的です。Propsの関係が複雑な場合は、型エイリアスを使用することがあります。型エイリアスは、プリミティブ型だけでなく、オブジェクト型、ユニオン型、タプル型、および交差型を表すために使用できます。型エイリアスは、typeキーワードを使って宣言します。{score}</h1>)また、型に名前を与えることで可読性が向上します。number[];変数と同様に、同じ型のエイリアスを複数回宣言することはできません。TypeScriptがエイリアスを推論することはなく、明示的に型注釈しなければなりません。以下は、型エイリアスを使った例です。personMail};console.log(person);コンソールの出力は下記で確認可能です。https://codepen.io/enjinia_f/pen/YzawvzP/?editors=1011上記の例では、型エイリアスを使用して、Personオブジェクトのプロパティの型を明示的に指定しています。これにより、コードの可読性が向上し、保守性が向上します。宣言のマージと拡張ReactとTypeScriptの組み合わせで、Propsを扱う際に非常に重要な機能があります。それは、型の定義方法に関するものです。TypeScriptでは、型エイリアスとinterfaceの2つの型の定義方法があります。型エイリアスは、既存の型に対して別名を付けるためのもので、下記のように定義することができます。string;一方、interfaceは、オブジェクトの形状を定義するためのもので、下記のように定義することができます。number;}このように、型エイリアスとinterfaceはそれぞれ異なる目的を持っていますが、いくつかの点で異なる振る舞いをすることがあります。宣言のマージについて考えてみましょう。宣言のマージとは、TypeScriptコンパイラが同じ名前を持つ2つ以上のinterfaceを1つにマージすることです。下記のように2つのinterfaceを定義することができます。number;}この場合、TypeScriptは自動的に両方のinterfaceをマージして、下記のように解釈します。number;}一方、型エイリアスでは宣言のマージは行われません。同じ名前の型エイリアスを複数回定義すると、エラーが発生します。'MyType'次に、型の拡張について考えてみましょう。interfaceは、他のinterfaceを拡張することができます。これにより、元のinterfaceに新しいプロパティを追加したり、既存のプロパティを上書きすることができます。下記は、interfaceを拡張する例です。1000};一方で、型エイリアスは拡張ができません。同じ名前の型エイリアスを定義することはできますが、既存の型に対して新しいプロパティを追加することはできません。propsReactにおいて、Propsを受け取ってレンダリングするChildren機能は、最も価値のある機能の1つです。propsを使用することで、コンポーネントをまとめて構成することができます。この概念は、再利用可能なコンポーネントを構築するために非常に重要です。親コンポーネントが子コンポーネントに直接何らかのコンテンツを渡すためには、マークアップまたはアクションでカプセル化するだけでよく、子コンポーネントはprops.children変数を通じて、渡されたchildrenにアクセスすることができます。配列、あるいは他のコンポーネントも可能です。型を明示的に定義することが望ましいです。これにより、TypeScriptを使用して型チェックを行うことができます。propsの型を定義する場合、いくつかのオプションがあります。JSX.ElementReactでは、Props.childrenプロパティの多くはJSX要素で構成されており、これらの要素を型付けするためにJSX.Elementという特別な型を使用できます。React要素は、コンポーネントやDOM要素を表すオブジェクトであり、JSX要素がJavaScriptに変換された結果として生成されます。JSX.Elementは、React環境でグローバルに利用できる特別な型です。コンポーネントがレンダリングされるとき、開始タグと終了タグの間に含まれるコンテンツを保持します。下記のように、Propsにtitleとchildrenを定義した場合です。children</span></Component>);};JSX.Element型は、子コンポーネントが受け取るReact要素の配列を表します。子コンポーネントは、この配列内のReact要素にアクセスし、それらをレンダリングすることができます。JSX.Elementは、childrenに使用できる最も制限的な型であり、Propsが単一のReact要素である場合にのみ機能します。他のプリミティブな値、例えば文字列などは、childrenに許可されていません。コンポーネントの消費者がこれをオプションにしたい場合は、?を付けた型注釈を使用することができます。JSX.Element;};ただし、JSX.Elementは複数の子要素を許可しません。複数の子要素を持つ場合、または文字列などのプリミティブなものを許可したい場合は、他のオプションを検討する必要があります。]JSX.Element[]は、複数のJSX要素を含む配列を表します。この型は、Reactで複数の要素をレンダリングする際によく使用されます。複数のJSX要素を許可しますが、文字列、数字などは許可しません。下記では、JSX.Element[]の型は明示的に定義していない事に注意してください。);}上記の例では、FruitListコンポーネントにfruitsプロパティが渡されます。fruitsプロパティは、Fruit型の配列であり、Fruit型は、name、colorの2つのプロパティを持ちます。FruitListコンポーネントでは、fruitsプロパティの各要素をレンダリングするために、mapメソッドを使用しています。mapメソッドは、各要素に対して、keyプロパティを指定したli要素を返します。li要素には、各フルーツのnameとcolorが含まれています。JSX.Element[]はReactの型の一つで、Reactライブラリの中で定義されています。FruitList関数コンポーネントは、JSX.Element[]の型を返すことが期待されており、JSX構文を使用してUIをレンダリングしています。そのため、TypeScriptはこの関数がJSX.Element[]の型を返すと推論し、型チェックを行います。したがって、上記のコードではJSX.Element[]の型を明示的に定義する必要はありません。このように、JSX.Element[]を使うことで、Reactで複数の要素を効率的にレンダリングすることができます。明示的にJSX.Element[]の型を定義する必要がある場合があります。下記のような場合です。返される要素がJSX.Element[]ではない場合たとえば、Reactコンポーネントが単一の要素を返すように定義されている場合、型推論が期待通りに機能しない場合があります。この場合、返される要素の型をJSX.Element[]として明示的に定義する必要があります。ネストされたコンポーネントの型が異なる場合ネストされたコンポーネントの型がJSX.Element[]と一致しない場合、明示的に型を定義する必要があります。外部ライブラリで定義されたコンポーネントを使用する場合、そのコンポーネントの型がJSX.Element[]と一致しない場合があります。この場合、明示的に型を定義する必要があります。以上のような場合、JSX.Element[]の型を明示的に定義することで、TypeScriptはコードをより厳密にチェックできるようになります。JSX.Element[]は、単一または複数のJSX要素を表します。この型は、コンポーネントのプロパティで単一の要素または複数の要素の配列を受け取ることができる場合に使用されます。文字列や数字などのプリミティブ型は許可されず、JSX要素のみが許可されます。JSX.Element[]型であり、単一のJSX要素やJSX要素の配列を受け取ることができます。これを使って、Reactアプリケーションでメッセージを表示する場合、下記のように記述することができます。<span>こちらは、複数のJSX要素を許可します。);}上記のコードでは、Messageコンポーネントを定義し、childrenプロパティで受け取った要素を表示しています。Appコンポーネントでは、Messageコンポーネントに複数のJSX要素を渡しています。Messageコンポーネントは、受け取ったnoticeプロパティに応じてメッセージを表示するようになっています。これにより、Reactアプリケーションで複数の要素を組み合わせたメッセージを表示することができます。上記以外の、選択できる型はございます。React.ReactChild1つのReact要素、文字列、または数値を許可します。{children}!</div>;}上記の例では、Greetingコンポーネントにchildrenプロパティが渡されます。childrenプロパティは、ReactChild型であり、文字列、数値、React要素など、さまざまな種類の要素を受け取ることができます。Greetingコンポーネントでは、childrenプロパティを含むdiv要素を返します。childrenプロパティの値が、Hello,という文字列の前に表示されます。]ReactChild[]は、単一の要素や配列を含むことができるReact要素の配列を表します。childrenプロパティが渡されます。ReactChild型の配列であり、文字列や数値、React要素など、複数の種類の要素を含むことができます。childrenプロパティの各要素をレンダリングするために、mapメソッドを使用しています。span要素を返します。span要素には、各子要素が含まれています。ReactChild[]を使うことで、Reactで複数の要素を効率的にレンダリングすることができます。]単一の要素または要素の配列を含むReact要素を表します。);}上記の例では、Messageコンポーネントにchildrenプロパティが渡されます。childrenプロパティは、ReactChild型またはReactChild型の配列であり、文字列や数値、React要素など、複数の種類の要素を含むことができます。Messageコンポーネントでは、childrenプロパティの型によって、単一の要素をレンダリングするか、配列をmapメソッドで反復処理してレンダリングするかを判断しています。ReactのisArrary関数を使用して、childrenが配列であるかどうかを判定し、配列の場合はmapメソッドを使用して各要素をレンダリングします。単一の要素の場合は、childrenを直接レンダリングします。ReactChild[]を使うことで、Reactで単一の要素または複数の要素をレンダリングすることができます。フラグメント、ポータルを許可します。CodePen.上記の例では、Messageコンポーネントにmessageプロパティが渡されます。messageプロパティは、React.ReactNode型であり、文字列や数値、React要素など、複数の種類の要素を含むことができます。Messageコンポーネントでは、messageプロパティを直接レンダリングしています。上記のように、React.ReactNodeを使うことで、Reactでさまざまな種類の要素をレンダリングすることができます。TypeScriptの型定義です。これは、文字列、数値、Reactコンポーネント、null、undefined、またはこれらの型の配列のいずれかを表すことができます。React.ReactNode[]は、ReactNodeの配列を表します。React.ReactNode[]型のlistプロパティが含まれています。関数コンポーネントは、ExampleComponentにtextとlistを渡します。メソッドでループし、各要素を<span>要素として含む配列に変換されます。childrenのおさらいも含めて、他の例でも見ていきましょう。JSX.Element;};タグなしでPropsオブジェクトを作成できることをコンパイラに通知します。JSX.Elementは、子要素が単一のReact要素であることが要求される場合はよいでしょう。複数の子要素は許しません。そこで、下記のように調整します。JSX.Element[];};ですが、JSX.Elementの欠点は文字列を許さないことです。そこで、ユニオン型に文字列を追加することができます。string[];};ですが、数字についてはどうでしょうか?幸いなことに、React.ChildというReact要素は、文字列、数字を含む標準の型があります。そこで、下記のように子要素の型を広げることができます。React.ReactChild[];};React.ReactChild|React.ReactChild[]は、必要な値の幅を与えてくれますが、少し冗長となってます。ReactNodeは、より簡潔なオプションです。フラグメント、ポータルを使用できます。propsに渡すことができるすべての要素の型を表します。他の例でも、見てみましょう。下記のコードでは、ReactのReactNode型を使用して、子コンポーネント内でprops.childrenの型を正しく指定しています。これにより、子コンポーネントがprops.childrenを使用する場合に、その値の型が適切に推論され、親コンポーネントから渡された要素が子コンポーネント内で適切に型付けされるようになります。);}これにより、親コンポーネントから渡された要素が、子コンポーネント内で適切に型付けされ、コンポーネント間で正しく伝達されるようになります。フラグメント、ポータルなど、子要素として使用できるすべての要素の型を表します。したがって、props.childrenに渡される要素がどのような型であっても、ReactNode型を使用することで、その値を適切に型付けすることができます。型エラーの検証TypeScriptを使用することで、ReactアプリケーションにおいてPropsの間違ったセットや値の型に対して、コンパイル時に警告を表示させることができます。Propsにstring型が指定されているプロパティに対して数値を渡した場合、TypeScriptはエラーをスローし、このバグを早期に発見することができます。下記の例では、MyMessageコンポーネントに、messageプロパティに数値型の値が渡されていますが、Propsのインターフェースでstring型が指定されているため、TypeScriptはコンパイルエラーをスローします。</div>;}上記のように、TypeScriptによってコンパイル時にエラーが検出されるため、このエラーはコードベースに隠れることなく、開発中に早期に修正することができます。Propsの必要なすべてのプロパティを渡さない場合も、コンパイルエラーが発生します。読み取り専用プロパティの指定interfaceのプロパティを読み取り専用としてマークすることもできます。これを行うには、プロパティのキーの前にreadonlyキーワードを追加します。Date;};読み取り専用プロパティは、オブジェクトが最初に作成されたときにのみ変更可能であり、再割り当てしようとするとコンパイラはエラーをスローします。このように、読み取り専用プロパティを使用することで、不必要にプロパティが変更されるのを防止し、安全なコーディングを実現することができます。React.FCとReact.VFCについてReact.FCとReact.VFCは、Reactで関数コンポーネントを記述するための汎用的なインターフェースです。Componentの略で、アロー関数を使って書かれたコンポーネントの標準的な型です。Componentの略で、戻り値がvoidである関数コンポーネントの型です。18のリリース以降は含まれなくなりました。propsを明示的に指定しなければなりません。propsを含めませんでした。18のリリース以降、React.FCには暗黙の子が含まれなくなり、React.VFCはCRAのテンプレートで非推奨になり削除されました。propsを含むかどうかはReact.FCとReact.VFCの違いではなく、コンポーネントの実装によって異なります。そのため、React.FCとReact.VFCのどちらを使用するかは好みの問題になります。パフォーマンスへの影響は大きくはありませんが、React.FCおよびReact.VFCは、特にコードベースが大規模になる場合には制限と欠点があります。したがって、これらの型に依存せず、状況に応じて最適な型を選択することが重要です。初学者の方は、これらの型について無理に学ぶ必要はありません。これらの型が使用されているコードを読む必要がある場合は、その意味を理解しておくことが役立ちます。最後にTypeScriptは、Reactでの開発において優れたツール機能と型の安全機能を提供しています。そのため、Reactで多くの型付けや定型コードを記述する必要はありません。Reactでは、コンポーネントが非常に重要であり、必要なものが数回のキーストロークで揃います。ReactコンポーネントはTypeScriptから大きな恩恵を受けることができます。TypeScriptの型システムは、コンポーネントのPropsを検証する際に特に役立ちます。この機能により、入力値が適切かどうかを事前に確認することができます。以上が本日の記事の内容です。最後まで読んで頂きありがとうございます。この記事が役に立ったら、ブックマークと共有をしていただけると幸いです。17:56ご訪問いただきありがとうございます。私はdeve.Kと申します。現役のReact.jsプログラマーでありWebアプリ開発に携わっています。当ブログでは、ITやプログラミングの学習を目的としたブログを運営しています。専門分野はJS/TS/Node.js/React/Next.jsです。質問や相談、または学びたい分野のリクエストなどがありましたら、お気軽にお問い合わせください。このブログでは、ITやプログラミングに関する情報を分かりやすく、かつ実践的な内容でお届けしています。皆様にとって有益な情報を提供し、より良い学習体験を得ていただけるよう、精一杯の努力をしてまいります。今後ともどうぞよろしくお願いいたします。[deve.K].はてなブログをはじめよう!dev04Kさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。