【React.js】React.jsにおけるコンポーネントとpropsの使い方をご紹介!
目次
前回までは、React.jsの概要と環境構築、Hello Worldの表示までをご紹介しました。
前回の記事をまだご覧でない方はそちらからご覧ください。
【React.js】React.jsとは?環境構築やHello World表示までをご紹介
https://www.dailyupblog.com/web_development/1830/
今回は、React.jsにおけるコンポーネントとpropsの使い方を紹介しようと思います。
それに付随して、ディレクトリ構成とJSXについても合わせてご紹介します。
React.jsのディレクトリ構成
コンポーネントを紹介する前に、React.jsのプロジェクトフォルダのディレクトリ構成を軽く紹介しようと思います。
プロジェクトフォルダ内のデータですが、基本的にsrc直下のもの以外は触ることはありません。
なので今回は、srcフォルダ内のディレクトリ構成に限って、紹介していこうと思います。
ですが、基本的には決まった形はありません。
なので、開発者の好みのディレクトリ構成で問題ないですが、公式が推奨している構成があります。
今回は、一例として、筆者が考えたディレクトリ構成を紹介します。
作成したばかりのReact.jsのプロジェクトフォルダ内は下記のような構成になっています。
src
├ App.css
├ App.test.tsx
├ App.tsx
├ index.css
├ index.tsx
├ logo.svg
├ react-app-env.d.ts
├ reportWebVitals.ts
└ setupTests.ts
ここから、コンポーネントのディレクトリやapiのディレクトリなどフォルダを分けていくわけです。
src
├ pages(各ページのtsxを格納)
├ components(コンポーネントを格納)
├ api(api呼び出しに関する処理を格納)
├ constants(定数ファイルなどを格納)
├ hooks(汎用的なhooksを格納)
├ lib(ライブラリの初期設定ファイルなどを格納)
├ style(グローバルなcssファイルを格納)
├ App.css
├ App.test.tsx
├ App.tsx
├ index.css
├ index.tsx
├ logo.svg
├ react-app-env.d.ts
├ reportWebVitals.ts
└ setupTests.ts
これはあくまで一例ですので、ご自身もしくはチーム全体で最適だと思うディレクトリ構成で開発をしましょう。
公式にも、ディレクトリ構成は考えすぎないようにしましょう、とあります。
ファイル構成 – React
https://ja.reactjs.org/docs/faq-structure.html
JSX記法について
React.jsでは、JSX記法という書き方でHTMLを描画します。
JSX記法とは、JavaScriptの中でHTMLを表現するJavScriptの拡張構文です。
React.jsにおけるJSX記法の例ですが、例えば下記です。
const Hello = () => {
return (
<div>
<h1>Hello World</h1>
</div>
)
}
上記のような形でReact.jsではHTMLを表現します。
JSX記法の具体的な書き方について軽くいくつか紹介します。
JavaScript式を{}でHTML内に埋め込む
JSX記法では、HTML内に{}でJavaScriptのコードを埋め込むことが可能です。
例えば、下記の例です。
const Hello = () => {
let hello = "Hello World";
return (
<div>
<h1>{hello}</h1>
</div>
)
}
コメントアウト
JSX記法における、コメントアウトは、通常のHTMLのコメントアウトは使えません。
その代わり、下記のようにコメントアウトできます。
return (
<div>
{/*<h1>{hello}</h1>*/}
</div>
)
空タグの書き方
JSX記法では、空タグにはタグの最後に「/」を書かなければなりません。
例えば、改行タグ「<br>」は「<br />」のように書かなければ、なりません。
return (
<div>
<br />
<h1>{hello}</h1>
</div>
)
フラグメント
JSX記法では、親要素は一つしか持てません。
例えば、下記のような例ではエラーになります。
return (
<h1>タイトル</h1>
<p>テキストテキストテキストテキストテキストテキスト</p>
)
なのでこれを一つの親要素で括ってやらなければなりません。
return (
<div>
<h1>タイトル</h1>
<p>テキストテキストテキストテキストテキストテキスト</p>
</div>
)
ですが、この書き方だと、不要なdivタグがついてしまうので、下記のような書き方をすれば、不要なタグも付かずに、簡略的に書くことができます。
return (
<>
<h1>タイトル</h1>
<p>テキストテキストテキストテキストテキストテキスト</p>
</>
)
属性について
JSX記法では、属性は通常のHTMLとは異なった書き方をしなければなりません。
例えば、class属性であれば、下記のようにキャメルケースでの書き方で書きます。
return (
<>
<h1 className="title">タイトル</h1>
<p>テキストテキストテキストテキストテキストテキスト</p>
</>
)
コンポーネントについて
reactにおいても、コンポーネントは重要な機能です。
vueの時も紹介した通り、モダンなフロントエンド開発において、コンポーネント指向での開発は主流になっています。
コンポーネントとは、UIを独立した再利用可能な部品に分割して、それらの部品単位で開発ができるものです。
reactにおいては、コンポーネントには関数コンポーネントとクラスコンポーネントの2種類が存在します。
これら、二つは機能としては同じものですが、書き方が異なるので、今回はどちらのパターンも紹介しようと思います。
関数コンポーネント
関数コンポーネントは、文字通り関数のようにコンポーネントを作成することができるものです。
戻り値として、JSXを返す構造になっています。
実際にコンポーネントを作成してみましょう。
srcディレクトリ直下に「components」フォルダを作成して、その中にHello.tsxファイルを作成してください。
今回は、単純にHello WorldのJSXを返すコンポーネントを作成します。
Hello.tsxに下記のように記述してください。
const Hello = () => {
return (
<div>
<h1>Hello World</h1>
</div>
)
}
export default Hello;
関数コンポーネントは上記のように記述します。
※今回は、ES6で導入されたアロー関数を使用しています。
最後にちゃんとexport defaultしましょう。
const 関数名 = () => {
return JSX
}
export default 関数名
この作成したコンポーネントを呼び出してみようと思います。
srcディレクトリ直下のindex.tsxを開き、下記のように修正してください。
import React from 'react';
import ReactDOM from 'react-dom/client';
import Hello from './components/Hello'; //追記
import './index.css';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<Hello /> //修正
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
これでコンポーネントの呼び出しは完了です。
ブラウザから「http://localhost:3000/」にアクセスしてみてください。
下記のようにHello Worldが表示されればOKです。
クラスコンポーネント
クラスコンポーネントは、JavaやC言語学習者であれば馴染み深いクラスを用いてコンポーネントを作成する方法です。
クラスコンポーネントは、React.Componentを拡張するJavaScriptクラスであり、ES6に沿った記述をします。
先ほど、関数コンポーネントで記述したHello Worldコンポーネントをクラスコンポーネントで記述すると、下記のようになります。
import { Component } from "react";
class Hello extends Component {
render() {
return (
<div>
<h1>Hello World</h1>
</div>
)
}
}
export default Hello;
関数コンポーネントと比べてコード量が多いのがわかると思います。
React.Componentを利用するため、インポートしており、JSXはrenderメソッド内で返されます。
import { Component } from "react";
class クラス名 extends Component {
render() {
return JSX
}
}
export default Hello;
関数コンポーネントは2019年までは機能が限定的であったため、クラスコンポーネントの方が使われていました。
ですが、2019年以降、関数コンポーネントで新たな機能としてHooksが導入されたため、関数コンポーネントで十分賄えるようになり、現在では関数コンポーネントを使用する方が主流のようです。
クラスコンポーネントに比べて、関数コンポーネントは少ないコード量で済むので、関数コンポーネントの方が簡単で見やすくメリットが多いわけです。
関数コンポーネントのHooks機能に関しては、別記事で紹介するので、今回は割愛します。
なお、今後は関数コンポーネントの方を使用していこうと思うので、これ以降はクラスコンポーネントの説明は省きます。
propsの使い方
propsとは、コンポーネントのインポートを行う側(親コンポーネント)からインポートされる側(子コンポーネント)にデータを渡す機能です。
今回は、関数コンポーネントにおけるpropsの使い方をを紹介します。
先ほど作成した、Hello.tsxファイルを下記のように書き換えてください。
type Props = {
message: string
}
const Hello= ({message}: Props) => {
return (
<div>
<h1>{message}</h1>
</div>
)
}
export default Hello;
TypeScriptでpropsを使うときは、propsの型宣言は、Typeエイリアスで事前に宣言した型を指定してあげるのが良いです。
上記の例だと、「Props」というTypeエイリアスにて、「message」というstring型の型宣言をしています。
ちなみに、TypeScriptのTypeエイリアスについては下記記事にまとめていますので、よければこちらも合わせてご覧ください。
型に別名をつける(Type Alias)
https://www.dailyupblog.com/languages/1717/#chapter-6
コンポーネントの呼び出し元であるindex.tsxを下記のように書き換えてみてください。
//省略・・・
root.render(
<React.StrictMode>
<Hello message="こんにちは" />
</React.StrictMode>
);
//省略・・・
ブラウザで確認してみてください。
下記のように表示されていれば、OKです。
最後に
今回は、Reactにおけるディレクトリ構造とJSX記法、コンポーネントとpropsの使い方について紹介いたしました。
コンポーネント指向のプログラミングはReactでの開発において最も重要な項目ですので、絶対にコンポーネントは使いこなせるようになりたいところです。
今回紹介したのは、基本的な使い方だけですので、是非実際に手を動かして、使ってみてください。
前回:【React.js】React.jsとは?環境構築やHello World表示までをご紹介
https://www.dailyupblog.com/web_development/1830/
次回:【React.js】useStateとuseEffectの使い方をご紹介(React hooksを学ぶ)
https://www.dailyupblog.com/web_development/1888/