色々調べながら作ってもいいのだが、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
では、計算モードに応じて入力フィールドを制御し、和または積を計算する機能を実装しています。また、
calcMode
とsetCalcMode
を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;
修正した部分では、
label
とselect
要素を使用してコンボボックスを表示し、選択した計算モードをsetCalcMode
関数を介して更新するようにしました。これにより、ボタンではなくコンボボックスで足し算と掛け算の切り替えが行えるようになります。
ばっちりだ。10分かからずにサンプルアプリが完成してしまった。 驚きを通り越して怖くなってくるレベル・・・。
さて、サンプルプログラムができたので、中身を紐解きながらReactの勉強をしていこう。