説明したいこと
- Reactのコンポーネントとは
- コンポーネントの種類
- コンポーネントの使い分け
- 単純なコンポーネントの作成方法
Reactとは
Facebookが開発したコンポーネント指向のUI構築ライブラリです。
コンポーネントとは
Reactはコンポーネントと呼ばれるUIの部品を組み合わせてアプリを構築していきます。コンポーネントは値を受け取ることができ、受け取った値により見た目、動きを変えます。
適度な粒度で独立したコンポーネントを作成していくことで、アプリ内の様々な箇所で使い回す事ができ、見やすいコードになると思います。
Reactでアプリを開発する際はこの、コンポーネントを 作っていくことが大半の作業になるかと思います。
Reactのコンポーネントには大きく分けて以下の2つの作り方があります。
- クラスコンポーネント (クラスでコンポーネントを定義)
- 関数コンポーネント (関数でコンポーネントを定義)
ですが、今からReactを始める場合は関数コンポーネントでの作り方だけ分かっていれば問題ないです。
というのも、以前までClass Componentでしかできないことがあったのですが、Hooksと呼ばれるものの登場により、できることに差がなくなったからです。
この記事の中では、関数コンポーネントのみを対象に説明していきます。
コンポーネントの作り方
用語
- Props : コンポーネントに渡されるパラメータ
- State : コンポーネントが持つ状態
- JSX : コンポーネントのUIの記述をする
コンポーネントの種類
Reactのコンポーネントには以下の2種類があります
- Presentational Component
- Container Component
Presentational Componentは見た目の定義だけをし、JSXを多く持ちます。
Container Componentはコンポーネントのロジックを定義します。
これらは、もともとはReduxと呼ばれるReactの状態管理を行うライブラリで用いられていたものですが、Reduxを使用していなくてもコンポーネントを見た目とロジックで分けることでコードが見やすく、管理もしやすくなると感じています。
呼び方としてははPresentational Componentをコンポーネント、Container Componentはコンテナと呼ぶことが多い気がします。
コンポーネントを作成してみる
今からこんな感じの、押した回数によってカウントが増えていくコンポーネントを例として作成します。
環境の構築
この記事では割愛させてもらいます🙇♂️
基本的にはcreate-react-app
で作成されたプロジェクトでTypeScriptを使用していくことを想定してます。
Presentational Componentの作成
コンポーネントを作成する際はまず、見た目を作成していきます。
ここでは、ボタンとクリック回数を表示するラベルという、good
とbad
で共通した部品を作ります。
import React, { FC } from "react";
// コンポーネントのProps(パラメータ)の型を定義
type RateButtonProps = {
buttonText: string;
clickedNumber: number;
onClick: () => void;
};
// 関数コンポーネント
export const RateButton: FC<RateButtonProps> = (props) => {
const { buttonText, clickedNumber, onClick } = props;
return (
<>
<button onClick={onClick}>{buttonText}</button>
<label> {clickedNumber}</label>
</>
);
};
このファイルを作成するだけでは画面上に表示されないので一時的に、App.tsx
をこんな感じにします。
import "./styles.css";
import { RateButton } from "./RateButton";
export default function App() {
return (
<>
{/* とりあえず表示するために固定を渡している */}
<RateButton buttonText='good👍' clickedNumber={0} onClick={() => console.log('clicked')} />
</>
);
}
※index.tsx
がApp.tsx
を読み込んで、その内容を表示する流れになっているのですが、細かい箇所は省略します。
Container Componentの作成
今のままだと、クリックしても何も反応しないものになってしまうので
コンテナを使用してロジックを書いていきます。
import React, { FC, useState } from "react";
import { RateButton } from "./RateButton";
type BadButtonContainerProps = {
buttonText: string;
};
export const BadButtonContainer: FC<BadButtonContainerProps> = (props) => {
// コンポーネントが持つ State(状態)
const [badNumber, setBadNumber] = useState<number>(0);
const addBadNumber = () => {
setBadNumber((preState) => preState + 1);
};
return (
<RateButton {...props} clickedNumber={badNumber} onClick={addBadNumber} />
);
};
コード上で出てきているuseState()
に関してですが、これは関数コンポーネントでState(状態)を保持できるようにした機能です。今回はクリックしたという動作に合わせてStateが変化していくのでコンテナにStateを持たせています。
これでBadボタンの動きまで作成できました。GoodボタンもベースとなるRateButton
は同じでStateの動きが異なるだけなので同様に作成します。
import React, { FC, useState } from "react";
import { RateButton } from "./RateButton";
type GoodButtonContainerProps = {
buttonText: string;
};
export const GoodButtonContainer: FC<GoodButtonContainerProps> = (props) => {
const [goodNumber, setGoodNumber] = useState<number>(0);
const addGoodNumber = () => {
setGoodNumber((preState) => preState + 1);
};
return (
<RateButton {...props} clickedNumber={goodNumber} onClick={addGoodNumber} />
);
};
あとはApp.tsx
を以下のように修正します。
import React from 'react';
import { BadButtonContainer } from "./BadButtonContainer";
import { GoodButtonContainer } from "./GoodButtonContainer";
export default function App() {
return (
<>
<GoodButtonContainer buttonText="good👍" />
<BadButtonContainer buttonText="bad👎" />
</>
);
}
これで完成です。
まとめ
この記事ではコンポーネントのみを対象に説明しました。