React propsを使ったデータの渡し方を理解する #2

JS

Reactにてpropsの基本的な使い方を紹介致します。propsはcomponent間でデータを渡す上で必要な概念になります。

以前以下の記事にてReactプロジェクトの始め方を紹介致しました。

React入門 React プロジェクトの始め方 #1
React プロジェクトを開始するにあたって、最初に知っておきたいことを簡潔にまとめました。ReactはJavaScriptライブラリであり、ユーザーインターフェースを構成することができます。ReactではComponentの概念が欠かせません。またJSXコードを理解しておく必要があります。

componentの基本が理解できたら、propsの理解を本記事で深めて頂ければと思います。

1.propsを通してデータを渡す

DBから取得したデータをcomponentへ渡したいと仮定します。

const expensesをダミーデータとして以下のように用意します。

ExpenseApp.js

import ExpenseItem from "../components/Expenses/ExpenseItem";

const ExpenseApp = () => {
  const expenses = [
    {title: 'Car Insurance', amount:94.12, date: new Date(2022,4,12)},
    {title: 'Book', amount:14.31, date: new Date(2022,5,30)},
    {title: 'Bag', amount:114.76, date: new Date(2022,6,19)},
    {title: 'Toy', amount:24.51, date: new Date(2022,7,3)}
  ];

  return (
    <div className="ExpenseApp">
      <ExpenseItem title={expenses[0].title} amount={expenses[0].amount} date={expenses[0].date} />
      <ExpenseItem title={expenses[1].title} amount={expenses[1].amount} date={expenses[1].date} />
      <ExpenseItem title={expenses[2].title} amount={expenses[2].amount} date={expenses[2].date} />
      <ExpenseItem title={expenses[3].title} amount={expenses[3].amount} date={expenses[3].date} />
    </div>
  )
};

export default ExpenseApp;

ExpenseItem componentには、title、amount、dateを渡します。

ExpenseItem.js

export default function ExpenseItem(props) {
  return (
    <div className="expense-item">
      <div className="expense-item__description">{props.date.toString()}</div>
      <div>
        <h2>{props.title}</h2>
        <div className="expense-item__price">{props.amount}</div>
      </div>
    </div>
  );
};

※ExpenseItem は functionで定義していますが、arrow functionで書いても大丈夫です。

arrow function の場合は、以下のような書き方になります。

const ExpenseItem = (props) => {};

export default ExpenseItem;

propsを引数に取ることで、データを受け取ることができます。

prop.titleと書くことでExpenseApp.jsからtitileの値が渡されます。

JSXコード内では{props.title}のように{}:中括弧で囲むことでJavaScriptの表現が使えるようになり、データを表示できます。

2.props childrenの使い方

開始と終了タグの間にデータを渡したい場合があります。

その場合に props.childrenでデータを渡せるようになります。

よく使う例としては、共通で使うレイアウトのcomponentを用意しておいて、そのレイアウトの中に子componentを間に挟むというケースです。

Card.js

import classes from './Card.module.css';

const Card = (props) => {
  return (
    <div className={`${classes.card} ${props.className}`}>{props.children}</div>
  )
};

export default Card;

Card.module.css

.card {
background: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
border-radius: 10px;
}

Card.module.cssのようにファイル名に「module」を含めて記載することができます。

JSファイルにimportする際は、以下のように記載します。

import classes from './Card.module.css'

classes の部分は適宜名前を付けることができます。

classNameにスタイリングを当てる際に、以下のように記載することでpropsで受け取ったclassName(スタイリング)も適用することができます。

<div className={`${props.className}`}></div>

 

ExpenseItem.js

import './ExpenseItem.css';
import Card from '../UI/Card';

export default function ExpenseItem(props) {
  return (
    <Card className='expense-item'>
      <div className="expense-item__description">{props.date.toString()}</div>
      <div>
        <h2>{props.title}</h2>
        <div className="expense-item__price">{props.amount}</div>
      </div>
    </Card>
  );
};

上記の例では、Card componentをレイアウトテンプレートとして、その間に表示したい内容をJSXコードで記載しています。

ExpenseItem.css

.expense-item {
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
padding: 0.5rem;
margin: 1rem 0;
border-radius: 12px;
background-color: #4b4b4b;
}

.expense-item__description {
display: flex;
flex-direction: column;
gap: 1rem;
align-items: flex-end;
flex-flow: column-reverse;
justify-content: flex-start;
flex: 1;
}

.expense-item h2 {
color: #3a3a3a;
font-size: 1rem;
flex: 1;
margin: 0 1rem;
color: white;
}

.expense-item__price {
font-size: 1rem;
font-weight: bold;
color: white;
background-color: #40005d;
border: 1px solid white;
padding: 0.5rem;
border-radius: 12px;
}

@media (min-width: 580px) {
  .expense-item__description {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    flex: 1;
  }

 .expense-item__description h2 {
   font-size: 1.25rem;
 }

 .expense-item__price {
   font-size: 1.25rem;
   padding: 0.5rem 1.5rem;
 }
}

ExpenseItem.cssのように「module」を含まない場合は上記のように、classNameにセレクタを指定します。

3.まとめ

Reactにてpropsを通してデータを渡す方法を紹介致しました。

propsを使うことで、文字列、数字、オブジェクトを渡すことができます。また関数(function)をポインターとして指し示すこともできます。

次の記事

React hook useStateの使い方を理解する #3
Event HandlerとuseStateについて紹介していきます。ユーザーがボタンを押下する、何か画面に入力するなどの操作をトリガーとして、定義したイベントを実行する仕組みになります。useStateと組み合わせて使うことがあるため、一緒に紹介します。