Next.jsで学ぶReact講座 | Reactの基本操作 – 金額と税率を受け取って税込み価格を出すコンポーネント

Next.js
スポンサーリンク

このテーマのゴール

ここでやりたいのは、「金額」と「税率」を props で受け取り、コンポーネントの中で計算して「税込み価格」を表示することです。
つまり、「見た目+計算ロジック」をひとつの部品としてまとめる練習です。

ポイントは 3 つです。
金額・税率を props で受け取る
コンポーネントの中で税込み価格を計算する
計算結果をきれいな形で表示する

これができると、「ちょっとしたビジネスロジックをコンポーネントに閉じ込める」感覚がつかめます。


まずは完成イメージのコードを見る

シンプルな税込み価格コンポーネント

// components/TaxPrice.tsx
type TaxPriceProps = {
  amount: number;   // 税抜き金額
  taxRate: number;  // 税率(例:0.1 = 10%)
};

export function TaxPrice({ amount, taxRate }: TaxPriceProps) {
  const taxIncluded = Math.round(amount * (1 + taxRate));

  return (
    <p>
      税抜き {amount.toLocaleString()} 円 → 税込み{" "}
      <strong>{taxIncluded.toLocaleString()} 円</strong>
    </p>
  );
}
TSX
// app/page.tsx
import { TaxPrice } from "./components/TaxPrice";

export default function Page() {
  return (
    <main style={{ padding: "24px", fontFamily: "system-ui, sans-serif" }}>
      <h1 style={{ fontSize: "22px", marginBottom: "16px" }}>
        税込み価格コンポーネントの例
      </h1>

      <TaxPrice amount={1000} taxRate={0.1} />
      <TaxPrice amount={2980} taxRate={0.1} />
      <TaxPrice amount={500} taxRate={0.08} />
    </main>
  );
}
TSX

画面には、例えばこんな感じで表示されます。

税抜き 1,000 円 → 税込み 1,100 円
税抜き 2,980 円 → 税込み 3,278 円
税抜き 500 円 → 税込み 540 円

同じ TaxPrice コンポーネントを使い回しつつ、金額と税率だけを変えているのがポイントです。


props で「金額」と「税率」を受け取る

型定義で「何を受け取るコンポーネントか」をはっきりさせる

まずはこの部分から。

type TaxPriceProps = {
  amount: number;   // 税抜き金額
  taxRate: number;  // 税率(例:0.1 = 10%)
};
TSX

ここでやっているのは、

このコンポーネントは
amount(税抜き金額)と taxRate(税率)という 2 つの数値を受け取ります

という“約束”を TypeScript で書いている、ということです。

これがあることで、

<TaxPrice amount="1000" taxRate={0.1} /> のように文字列を渡すとエラー
<TaxPrice amount={1000} /> のように taxRate を渡し忘れてもエラー

といった具合に、「間違った使い方」をコンパイル時に止めてくれます。

関数の引数で props を受け取る

次に、この部分。

export function TaxPrice({ amount, taxRate }: TaxPriceProps) {
  ...
}
TSX

これは、

  • TaxPriceTaxPriceProps 型のオブジェクトを受け取る
  • そのオブジェクトから amounttaxRate を取り出して使う

という意味です。

イメージとしては、こう呼ばれている感じです。

TaxPrice({ amount: 1000, taxRate: 0.1 });
TaxPrice({ amount: 2980, taxRate: 0.1 });
TaxPrice({ amount: 500, taxRate: 0.08 });
TSX

JSX では <TaxPrice amount={1000} taxRate={0.1} /> と書きますが、
中身では「{ amount: 1000, taxRate: 0.1 } というオブジェクト」が渡されている、と考えると分かりやすいです。


税込み価格の計算ロジックをコンポーネントに閉じ込める

計算式をちゃんと理解する

税込み価格の計算はシンプルです。

税込み価格 = 税抜き金額 × (1 + 税率)

例えば、税抜き 1,000 円・税率 10% の場合は、

1,000 × (1 + 0.1) = 1,000 × 1.1 = 1,100

これをそのままコードにすると、こうなります。

const taxIncluded = Math.round(amount * (1 + taxRate));
TSX

ここで Math.round を使っているのは、小数点を四捨五入して整数にするためです。
金額はふつう「1円単位」で扱うので、
2980 * 1.1 = 3278.0000000004 のような微妙な誤差をきれいに丸めてあげています。

表示を少しだけ“人間向け”にする

そのまま数字を表示してもいいのですが、
toLocaleString() を使うと「3,278」のようにカンマ区切りにできます。

<p>
  税抜き {amount.toLocaleString()} 円 → 税込み{" "}
  <strong>{taxIncluded.toLocaleString()} 円</strong>
</p>
TSX

ここでやっていることは、

税抜き金額も税込み金額も、toLocaleString() で見やすくしている
税込み金額は <strong> で少し強調している

という、ちょっとした UX の工夫です。
こういう「小さな気配り」をコンポーネントの中に閉じ込めておくと、
どこで使っても同じクオリティで表示されるようになります。


親コンポーネントから「金額」と「税率」を変えて使い回す

使う側は「値を渡すだけ」で済む

page.tsx 側のコードをもう一度見てみます。

<TaxPrice amount={1000} taxRate={0.1} />
<TaxPrice amount={2980} taxRate={0.1} />
<TaxPrice amount={500} taxRate={0.08} />
TSX

やっていることはとてもシンプルで、

1つ目の行では「税抜き 1,000 円・税率 10%」
2つ目の行では「税抜き 2,980 円・税率 10%」
3つ目の行では「税抜き 500 円・税率 8%」

という“条件”だけを渡しているだけです。

計算式や表示の仕方は、全部 TaxPrice コンポーネントの中に隠れている。
使う側は「金額と税率を渡せば、いい感じに税込み価格を出してくれる部品」として扱える。

これが「ロジックをコンポーネントに閉じ込める」ことの強さです。


まとめ:このコンポーネントからつかんでほしいこと

この「金額と税率を受け取って税込み価格を出すコンポーネント」で、つかんでほしいのは次の感覚です。

コンポーネントは「見た目」だけでなく「計算ロジック」も一緒に持てる
変わるのは「入力値(amount, taxRate)」で、計算式と表示は毎回同じ
props に型をつけることで、「このコンポーネントは何を受け取るのか」がはっきりする

ここが腑に落ちると、

割引後価格を出すコンポーネント
送料込みの合計金額を出すコンポーネント
ポイント還元額を計算して表示するコンポーネント

みたいな「ちょっとしたビジネス計算」を、どんどん部品として切り出せるようになります。

もしよければ、この TaxPrice を少しアレンジしてみてください。
例えば「税額(いくら税金が乗ったか)」も一緒に表示するようにすると、
taxAmount = taxIncluded - amount みたいな“派生値”をどう扱うか、さらに感覚が深まります。

タイトルとURLをコピーしました