ST_FUNC開発日記

建築構造設計Excelアドイン開発の記録

Reactサンプルプログラムの作成

色々調べながら作ってもいいのだが、ChartGPTさんがいることだし、さくっとサンプルのアプリケーションを作ってもらおう。

断面性能を計算するアプリケーションをイメージして以下のようなアプリケーションを作ってもらう。

Reactを利用して、簡単な計算を実施するアプリを作成したいです。
indexページはタイトルとロゴを表示します。
ハンバーガーメニューでページを切り替えます。
calcページに移動すると以下の機能があります。
* 3つの数をinputフィールドに入力したらその和を表示します。
* 2つの数をinputフィールド入力したらその積を表示します。
* この2つの機能はメニューなどで切り替えることができます。
* 機能を切り替えると、inputのフィールドの数が適切に切り替わります。
以上のソースコードを提案してください。
ReactのプロジェクトはTypeScriptで作成しています。

以下回答

以下は、ReactとTypeScriptを使用して提案された機能を実装したソースコードの例です。

まず、プロジェクトのフォルダに移動して、必要なパッケージをインストールします。

cd your-project-folder
npm install react-router-dom

次に、以下のコードを含むApp.tsxファイルを作成します。

import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

// Components
import Home from './Home';
import Calculator from './Calculator';

const App: React.FC = () => {
  const [calcMode, setCalcMode] = useState<'sum' | 'product'>('sum');

  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/calc">Calculator</Link>
            </li>
          </ul>
        </nav>

        <Route path="/" exact component={Home} />
        <Route path="/calc" render={() => <Calculator calcMode={calcMode} setCalcMode={setCalcMode} />} />
      </div>
    </Router>
  );
};

export default App;

次に、Home.tsxファイルとCalculator.tsxファイルを作成します。

Home.tsx:

import React from 'react';

const Home: React.FC = () => {
  return (
    <div>
      <h1>Welcome to Calculator App</h1>
      <img src="logo.png" alt="Logo" />
    </div>
  );
};

export default Home;

Calculator.tsx:

import React, { useState } from 'react';

interface CalculatorProps {
  calcMode: 'sum' | 'product';
  setCalcMode: React.Dispatch<React.SetStateAction<'sum' | 'product'>>;
}

const Calculator: React.FC<CalculatorProps> = ({ calcMode, setCalcMode }) => {
  const [num1, setNum1] = useState('');
  const [num2, setNum2] = useState('');
  const [num3, setNum3] = useState('');
  const [result, setResult] = useState<number | undefined>(undefined);

  const handleCalculation = () => {
    if (calcMode === 'sum') {
      const sum = parseFloat(num1) + parseFloat(num2) + parseFloat(num3);
      setResult(sum);
    } else if (calcMode === 'product') {
      const product = parseFloat(num1) * parseFloat(num2);
      setResult(product);
    }
  };

  return (
    <div>
      <h2>Calculator</h2>
      <div>
        <label>Number 1:</label>
        <input type="number" value={num1} onChange={(e) => setNum1(e.target.value)} />
      </div>
      <div>
        <label>Number 2:</label>
        <input type="number" value={num2} onChange={(e) => setNum2(e.target.value)} />
      </div>
      {calcMode === 'sum' && (
        <div>
          <label>Number 3:</label>
          <input type="number" value={num3} onChange={(e) => setNum3(e.target.value)} />
        </div>
      )}
      <button onClick={handleCalculation}>Calculate</button>
      <div>
        Result: {result !== undefined ? result : 'Please calculate'}
      </div>
      <div>
        <button onClick={() => setCalcMode('sum')}>Calculate Sum</button>
        <button onClick={() => setCalcMode('product')}>Calculate Product</button>
      </div>
    </div>
  );
};

export default Calculator;

このコードでは、App.tsxでルーティングを設定し、ホームページと計算機能ページを切り替えることができます。Calculator.tsxでは、計算モードに応じて入力フィールドを制御し、和または積を計算する機能を実装しています。

また、calcModesetCalcModeをpropsとして受け取り、計算モードを切り替えるボタンを追加しています。

さすがである。

いわれたとおりに

$ npm install react-router-dom

とインストールして、コードをそのままコピペするとエラーが。

下記エラーが出ました。
ERROR in src/App.tsx:25:25
TS2322: Type '{ path: string; exact: true; component: FC<{}>; }' is not assignable to type 'IntrinsicAttributes & RouteProps'.
  Property 'exact' does not exist on type 'IntrinsicAttributes & RouteProps'.
    23 |         </nav>
    24 |
  > 25 |         <Route path="/" exact component={Home} />
       |                         ^^^^^
    26 |         <Route path="/calc" render={() => <Calculator calcMode={calcMode} setCalcMode={setCalcMode} />} />
    27 |       </div>
    28 |     </Router>

ERROR in src/App.tsx:26:29
TS2322: Type '{ path: string; render: () => Element; }' is not assignable to type 'IntrinsicAttributes & RouteProps'.
  Property 'render' does not exist on type 'IntrinsicAttributes & RouteProps'.
    24 |
    25 |         <Route path="/" exact component={Home} />
  > 26 |         <Route path="/calc" render={() => <Calculator calcMode={calcMode} setCalcMode={setCalcMode} />} />
       |                             ^^^^^^
    27 |       </div>
    28 |     </Router>
    29 |   );

以下回答

エラーメッセージによると、exactプロパティとrenderプロパティがRouteコンポーネントの型であるRoutePropsに存在しないためエラーが発生しています。これはReact Routerのバージョンによるものかもしれません。最新のReact Router v6ではexactプロパティは使用されず、Routeコンポーネントのpropsとして直接指定されるようになりました。

以下は、React Router v6に対応した修正したコードです。

import React, { useState } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';

// Components
import Home from './Home';
import Calculator from './Calculator';

const App: React.FC = () => {
  const [calcMode, setCalcMode] = useState<'sum' | 'product'>('sum');

  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/calc">Calculator</Link>
            </li>
          </ul>
        </nav>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/calc" element={<Calculator calcMode={calcMode} setCalcMode={setCalcMode} />} />
        </Routes>
      </div>
    </Router>
  );
};

export default App;

上記の修正により、Routeコンポーネントexactプロパティとrenderプロパティを使用せず、代わりにelementプロパティを使用するようになりました。これによりReact Router v6に対応したコードになります。

動いたぞ!本当にChatGPT半端ない・・・。

あとはイメージで

足し算と掛け算の切り替えをボタンではなく、コンボボックスで切り替えるようにしてください。

以下回答

コンボボックスを使用して足し算と掛け算の切り替えを実装するために、Calculator.tsxファイルの一部を変更します。以下が修正されたコードです。

import React, { useState } from 'react';

interface CalculatorProps {
  calcMode: 'sum' | 'product';
  setCalcMode: React.Dispatch<React.SetStateAction<'sum' | 'product'>>;
}

const Calculator: React.FC<CalculatorProps> = ({ calcMode, setCalcMode }) => {
  const [num1, setNum1] = useState('');
  const [num2, setNum2] = useState('');
  const [num3, setNum3] = useState('');
  const [result, setResult] = useState<number | undefined>(undefined);

  const handleCalculation = () => {
    if (calcMode === 'sum') {
      const sum = parseFloat(num1) + parseFloat(num2) + parseFloat(num3);
      setResult(sum);
    } else if (calcMode === 'product') {
      const product = parseFloat(num1) * parseFloat(num2);
      setResult(product);
    }
  };

  return (
    <div>
      <h2>Calculator</h2>
      <div>
        <label>Calculation Mode:</label>
        <select value={calcMode} onChange={(e) => setCalcMode(e.target.value as 'sum' | 'product')}>
          <option value="sum">Addition</option>
          <option value="product">Multiplication</option>
        </select>
      </div>
      <div>
        <label>Number 1:</label>
        <input type="number" value={num1} onChange={(e) => setNum1(e.target.value)} />
      </div>
      <div>
        <label>Number 2:</label>
        <input type="number" value={num2} onChange={(e) => setNum2(e.target.value)} />
      </div>
      {calcMode === 'sum' && (
        <div>
          <label>Number 3:</label>
          <input type="number" value={num3} onChange={(e) => setNum3(e.target.value)} />
        </div>
      )}
      <button onClick={handleCalculation}>Calculate</button>
      <div>
        Result: {result !== undefined ? result : 'Please calculate'}
      </div>
    </div>
  );
};

export default Calculator;

修正した部分では、labelselect要素を使用してコンボボックスを表示し、選択した計算モードをsetCalcMode関数を介して更新するようにしました。これにより、ボタンではなくコンボボックスで足し算と掛け算の切り替えが行えるようになります。

ばっちりだ。10分かからずにサンプルアプリが完成してしまった。 驚きを通り越して怖くなってくるレベル・・・。

さて、サンプルプログラムができたので、中身を紐解きながらReactの勉強をしていこう。

Sampleアプリケーションの作成 · st-func/st-func-web@1491d65 · GitHub