前提・実現したいこと
- Reactで、縦×横×高さで直方体の体積を求める表計算を作っています。
各行毎に個別の直方体を計算しており、行数は増やしたり減らしたりできます。
- 行毎の体積計算はできていますが、体積の合計を求める所をどうしたらいいか分からないです。
該当のソースコード
- 現状のコードは、下記codesandboxにあげています。
https://codesandbox.io/s/20211124-tablemultiple-47vp9?file=/src/App.js
-
念のため、本質問の最後にコード全文を載せています。
-
現状の実装では、親の方で、下記のように行数(直方体の数)のみを管理しています。
const [numberOfRectangulars, setNumberOfRectangulars] = useState(1);
-
子コンポーネントの方で、Row関数を定義し、個別の直方体の数値管理、計算、表示を担っています。
-
行数が、例えば2行とか固定されていれば処理できると思うのですが、増減する場合、どのようにしたら集計できるのか分かりません。
試したこと
- 下記のような案を考えて実装しようとしました。
1.直方体のクラスを作る。
React
1class Rectangular { 2 constructor(vertical, horizontal, height) { 3 this.vertical = vertical; 4 this.horizontal = horizontal; 5 this.height = height; 6 } 7 }
2.番号リスト行追加時に子コンポーネントであるRowにpropsで渡してインスタンスを作る
(親側)
React
1<Row Rectangular={Rectangular} />
(子側)
React
1const [Rectangular] = props 2const rectangular = new Rectangular(0,0,0)
3.入力した結果を親に戻す。
React
1[rectanculars, setRectangulars] = useState([])
4.親の方でrectangularsをforループ等して、合計を計算する。
- しかし、そもそも、Rectangularというクラスを子コンポーネントに渡すことができず、②の時点で失敗しています。
Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a Symbol.iterator method.
何かお気づきの方、ご教示頂けたら幸いです。
よろしくお願いいたします。
コード全文
React
1import { useState, useEffect } from "react"; 2 3export default function App() { 4 const [numberOfRectangulars, setNumberOfRectangulars] = useState(1); 5 const [total, setTotal] = useState(0); 6 const decreaseCubes = () => { 7 if (numberOfRectangulars === 0) return; 8 setNumberOfRectangulars(numberOfRectangulars - 1); 9 }; 10 const increaseCubes = () => { 11 setNumberOfRectangulars(numberOfRectangulars + 1); 12 }; 13 14 return ( 15 <div className="App"> 16 <table className="table-auto my-10"> 17 <thead> 18 <tr> 19 <th className="px-4 py-2">縦</th> 20 <th className="px-4 py-2">横</th> 21 <th className="px-4 py-2">高さ</th> 22 <th className="px-4 py-2">体積</th> 23 </tr> 24 </thead> 25 <tbody> 26 {[...(Array(numberOfRectangulars) || 0)].map((key) => ( 27 <Row key={key} /> 28 ))} 29 </tbody> 30 <tfoot> 31 <tr> 32 <th colSpan="3">計</th> 33 <td className="text-right">{total}</td> 34 </tr> 35 </tfoot> 36 </table> 37 <button 38 className="rounded border-2 p-1 w-20 mx-2" 39 type="button" 40 onClick={decreaseCubes} 41 > 42 減らす 43 </button> 44 <button 45 className="rounded border-2 p-1 w-20 mx-2" 46 type="button" 47 onClick={increaseCubes} 48 > 49 増やす 50 </button> 51 </div> 52 ); 53} 54const Row = () => { 55 const [vertical, setVertical] = useState(0); 56 const [horizontal, setHorizontal] = useState(0); 57 const [height, setHeight] = useState(0); 58 const onChangeVertical = (event) => { 59 setVertical(event.target.value); 60 }; 61 const onChangeHorizontal = (event) => { 62 setHorizontal(event.target.value); 63 }; 64 const onChangeHeight = (event) => { 65 setHeight(event.target.value); 66 }; 67 const volume = vertical * horizontal * height; 68 return ( 69 <tr> 70 <td> 71 <input 72 type="number" 73 value={vertical} 74 onChange={onChangeVertical} 75 className="rounded border-2 p-1 w-20 text-right" 76 /> 77 </td> 78 <td> 79 <input 80 type="number" 81 value={horizontal} 82 onChange={onChangeHorizontal} 83 className="rounded border-2 p-1 w-20 text-right" 84 /> 85 </td> 86 <td> 87 <input 88 type="number" 89 value={height} 90 onChange={onChangeHeight} 91 className="rounded border-2 p-1 w-20 text-right" 92 /> 93 </td> 94 <td className="text-right">{volume}</td> 95 </tr> 96 ); 97}; 98
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2021/11/29 09:51