成果物
今回作成したのはCounterコンポーネントとNameコンポーネントを合わせたものになります。
CounterコンポーネントとNameコンポーネントのように、それぞれ機能単位でコンポーネントにまとめながらアプリケーションを開発することをコンポーネント指向
といいます。
CounterコンポーネントとNameコンポーネントをそれぞれ別のファイルに記述しエクスポートしてまとめます。
コード
index.js
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
App.js
import React, { useState } from "react";
import "./styles.css";
// CounterコンポーネントとNameコンポーエントをインポートする
import { Counter } from "./Counter";
import { Name } from "./Name";
// 初期値を設定
const INITIAL_COUNT = 0;
const INITIAL_NAME = "";
export default function App() {
// カウントAの現在の状態変数countA、カウントAの状態を更新する関数setCountAを定義
const [countA, setCountA] = useState(INITIAL_COUNT);
// カウントBの現在の状態変数countB、カウントBの状態を更新する関数setCountBを定義
const [countB, setCountB] = useState(INITIAL_COUNT);
// カウントAとカウントBの合計値であるカウントABの現在の状態変数countABを定義
// カウントABの状態を更新する関数setCountABを設定
const [countAB, setCountAB] = useState(INITIAL_COUNT);
// 姓の現在の状態変数firstName、姓の状態を更新する関数setFisrtNameを定義
const [firstName, setFirstName] = useState(INITIAL_NAME);
// 名の現在の状態変数lastName、名の状態を更新する関数setLastNameを定義
const [lastName, setLastName] = useState(INITIAL_NAME);
// 1ずつカウントアップする関数countAIncrementを定義
const countAIncrement = () => setCountA((prevCount) => prevCount + 1);
// 1ずつカウントダウンする関数countAIncrementを定義
const countADecrement = () => setCountA((prevCount) => prevCount - 1);
// 1ずつカウントアップする関数countBIncrementを定義
const countBIncrement = () => setCountB((prevCount) => prevCount + 1);
// 1ずつカウントダウンする関数countBIncrementを定義
const countBDecrement = () => setCountB((prevCount) => prevCount - 1);
// 設定された値をリセットする関数countResetを定義
// カウントA、カウントB、カウントAB(カウントAとカウントBの合計値)をリセットする
const countReset = () => {
setCountA(INITIAL_COUNT);
setCountB(INITIAL_COUNT);
setCountAB(INITIAL_COUNT);
};
// カウントAとカウントBを合計する関数countSumを定義
const countSum = () => {
setCountAB(countA + countB);
};
// フォームに入力された値(姓)を設定する関数setFirstNameを定義
const handleFirstName = (e) => setFirstName(e.target.value);
// フォームに入力された値(名)を設定する関数setFirstNameを定義
const handleLastName = (e) => setLastName(e.target.value);
// 状態変数firstName、lastNameに設定された値をリセットする関数nameResetを定義
const nameReset = () => {
setFirstName(INITIAL_NAME);
setLastName(INITIAL_NAME);
};
return (
<>
// Counterコンポーエントに以下の値、関数を渡す
<Counter
countA={countA}
countB={countB}
countAB={countAB}
countAIncrement={countAIncrement}
countADecrement={countADecrement}
countBIncrement={countBIncrement}
countBDecrement={countBDecrement}
countReset={countReset}
countSum={countSum}
/>
<hr />
// Nameコンポーネントに以下の値、関数を渡す
<Name
firstName={firstName}
lastName={lastName}
handleFirstName={handleFirstName}
handleLastName={handleLastName}
nameReset={nameReset}
/>
</>
);
}
Counter.js
// 他のファイルでもCounterコンポーネントを利用できるようexportする
// 親コンポーネントであるAppから渡されたpropsを受け取る
export const Counter = (props) => {
return (
<>
<h1>Counterコンポーネント</h1>
<p>
A+B= <b>{props.countAB}</b>
</p>
<div>
<p>
現在のカウントA:<b>{props.countA}</b>
</p>
// ボタンが押された際にカウントAを+1する
<button onClick={props.countAIncrement}>カウントA: +1</button>
// ボタンが押された際にカウントAを-1する
<button onClick={props.countADecrement}>カウントA: -1</button>
</div>
<div>
<p>
現在のカウントB:<b>{props.countB}</b>
</p>
// ボタンが押された際にカウントBを+1する
<button onClick={props.countBIncrement}>カウントB: +1</button>
// ボタンが押された際にカウントBを-1する
<button onClick={props.countBDecrement}>カウントB: -1</button>
</div>
<br />
// ボタンが押された際にカウントAとカウントBの値を合計する
<button onClick={props.countSum}>合計</button>
// ボタンが押された際にカウントA、カウントB、カウントAB(カウントAとカウントBの合計値)をリセットする
<button onClick={props.countReset}>リセット</button>
</>
);
};
Name.js
// 他のファイルでもNameコンポーネントを利用できるようexportする
// 親コンポーネントであるAppから渡されたpropsを受け取る
export const Name = (props) => {
return (
<>
<h1>Nameコンポーネント</h1>
<p>
私の名前は
<b>
{props.firstName} {props.lastName}
</b>
です
</p>
<div>
<label>姓:</label>
<input
type="text"
value={props.firstName}
// フォームに値が入力された、または削除された際に関数handleFirstNameを実行
onChange={props.handleFirstName}
/>
</div>
<div>
<label>名:</label>
<input
type="text"
value={props.lastName}
// フォームに値が入力された、または削除された際に関数handleLastNameを実行
onChange={props.handleLastName}
/>
</div>
<br />
// フォーム(姓、名)に入力された値と表示しているフルネームを削除する
<button onClick={props.nameReset}>リセット</button>
</>
);
};
styles.css
今回は記述なし
エクスポートとインポートの別の方法
今回の方法
今回は以下のようにエクスポートとインポートを行いました。
CounterコンポーネントとNameコンポーネントをそれぞれexportし、それぞれをAppコンポーネントでimportしました。
App.js
// 親コンポーネント
import { Counter } from "./Counter";
import { Name } from "./Name";
export default function App() {
// 省略
};
Counter.js
// 子コンポーネント
export const Counter = (props) => {
// 省略
};
Name.js
// 子コンポーネント
export const Name = (props) => {
// 省略
};
別の方法
インポート、エクスポートは以下のような方法でも可能です。
ポイントは2点あります。
-
ファイルの最後に
export default コンポーネント名
と記述する -
exportしたコンポーネントを
import コンポーネント名 from 相対パス
(コンポーネント名には{}
をつけない)
App.js
// 親コンポーネント
import Counter from "./Counter";
import Name from "./Name";
function App() {
// 省略
};
export default App;
Counter.js
// 子コンポーネント
const Counter = (props) => {
// 省略
};
export default Counter;
Name.js
// 子コンポーネント
const Name = (props) => {
// 省略
};
export default Name;