回答編集履歴
3
テキスト追加
answer
CHANGED
@@ -130,7 +130,7 @@
|
|
130
130
|
}
|
131
131
|
}
|
132
132
|
```
|
133
|
-
上記のクラス`Cube` は、質問に
|
133
|
+
上記のクラス`Cube` は、ご質問に添付のコードに含まれていた`class Rectangular` と同様のものです。以下はこのクラスを使った場合の修正箇所です。
|
134
134
|
|
135
135
|
```diff
|
136
136
|
import "./styles.css";
|
2
テキスト追加
answer
CHANGED
@@ -130,9 +130,8 @@
|
|
130
130
|
}
|
131
131
|
}
|
132
132
|
```
|
133
|
+
上記のクラス`Cube` は、質問にあるコードにある`class Rectangular` と同様のものです。以下はこのクラスを使った場合の修正箇所です。
|
133
134
|
|
134
|
-
以下は上記の`Cude`クラスを使った場合の修正箇所です。
|
135
|
-
|
136
135
|
```diff
|
137
136
|
import "./styles.css";
|
138
137
|
-import { useState, useEffect } from "react";
|
1
テキスト追加
answer
CHANGED
@@ -111,4 +111,181 @@
|
|
111
111
|
|
112
112
|
```
|
113
113
|
|
114
|
-
- ご質問にある codesandbox を fork して上記の修正を反映したもの ???? [20211124-tablemultiple-forked-1vh3h](https://codesandbox.io/s/20211124-tablemultiple-forked-1vh3h?file=/src/App.js)
|
114
|
+
- ご質問にある codesandbox を fork して上記の修正を反映したもの ???? [20211124-tablemultiple-forked-1vh3h](https://codesandbox.io/s/20211124-tablemultiple-forked-1vh3h?file=/src/App.js)
|
115
|
+
|
116
|
+
|
117
|
+
### 別案
|
118
|
+
|
119
|
+
stateを見直すことは同じですが、各直方体の3辺の情報自体を、Appのstate として持つというのもありかと思います。たとえば、以下のようなクラスを作り、これのインスタンスの配列 `cubes` を stateに持たせます。
|
120
|
+
```javascript
|
121
|
+
class Cube {
|
122
|
+
constructor(otherCube) {
|
123
|
+
this.vertical = otherCube ? otherCube.vertical : 0;
|
124
|
+
this.horizontal = otherCube ? otherCube.horizontal : 0;
|
125
|
+
this.height = otherCube ? otherCube.height : 0;
|
126
|
+
}
|
127
|
+
|
128
|
+
get volume() {
|
129
|
+
return this.vertical * this.horizontal * this.height;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
```
|
133
|
+
|
134
|
+
以下は上記の`Cude`クラスを使った場合の修正箇所です。
|
135
|
+
|
136
|
+
```diff
|
137
|
+
import "./styles.css";
|
138
|
+
-import { useState, useEffect } from "react";
|
139
|
+
-// import { Cube } from "./components/Cube";
|
140
|
+
+import { useState, useCallback } from "react";
|
141
|
+
+
|
142
|
+
+class Cube {
|
143
|
+
+ constructor(otherCube) {
|
144
|
+
+ this.vertical = otherCube ? otherCube.vertical : 0;
|
145
|
+
+ this.horizontal = otherCube ? otherCube.horizontal : 0;
|
146
|
+
+ this.height = otherCube ? otherCube.height : 0;
|
147
|
+
+ }
|
148
|
+
+
|
149
|
+
+ get volume() {
|
150
|
+
+ return this.vertical * this.horizontal * this.height;
|
151
|
+
+ }
|
152
|
+
+}
|
153
|
+
|
154
|
+
export default function App() {
|
155
|
+
- const [numberOfCubes, setNumberOfCubes] = useState(1);
|
156
|
+
- const [total, setTotal] = useState(0);
|
157
|
+
+ const [cubes, setCubes] = useState([new Cube()]);
|
158
|
+
+
|
159
|
+
const decreaseCubes = () => {
|
160
|
+
- if (numberOfCubes === 0) return;
|
161
|
+
- setNumberOfCubes(numberOfCubes - 1);
|
162
|
+
+ if (cubes.length === 0) return;
|
163
|
+
+ setCubes(cubes.slice(0, cubes.length - 1));
|
164
|
+
};
|
165
|
+
+
|
166
|
+
const increaseCubes = () => {
|
167
|
+
- setNumberOfCubes(numberOfCubes + 1);
|
168
|
+
+ setCubes([...cubes, new Cube()]);
|
169
|
+
};
|
170
|
+
|
171
|
+
+ const handleChangeCube = useCallback(
|
172
|
+
+ (selectedIndex, name, size) => {
|
173
|
+
+ setCubes(
|
174
|
+
+ cubes.map((cube, i) => {
|
175
|
+
+ if (i === selectedIndex) {
|
176
|
+
+ const newCube = new Cube(cube);
|
177
|
+
+ newCube[name] = size;
|
178
|
+
+ return newCube;
|
179
|
+
+ }
|
180
|
+
+ return cube;
|
181
|
+
+ })
|
182
|
+
+ );
|
183
|
+
+ },
|
184
|
+
+ [cubes]
|
185
|
+
+ );
|
186
|
+
+
|
187
|
+
return (
|
188
|
+
<div className="App">
|
189
|
+
<table className="table-auto my-10">
|
190
|
+
|
191
|
+
```
|
192
|
+
|
193
|
+
|
194
|
+
```diff
|
195
|
+
</tr>
|
196
|
+
</thead>
|
197
|
+
<tbody>
|
198
|
+
- {[...(Array(numberOfCubes) || 0)].map((key) => (
|
199
|
+
- <Row key={key} />
|
200
|
+
+ {cubes.map((cube, i) => (
|
201
|
+
+ <Row
|
202
|
+
+ key={`cube-${i}`}
|
203
|
+
+ cube={cube}
|
204
|
+
+ onChange={(name, size) => handleChangeCube(i, name, size)}
|
205
|
+
+ />
|
206
|
+
))}
|
207
|
+
</tbody>
|
208
|
+
<tfoot>
|
209
|
+
<tr>
|
210
|
+
<th colSpan="3">計</th>
|
211
|
+
- <td className="text-right">{total}</td>
|
212
|
+
+ <td className="text-right">
|
213
|
+
+ {cubes.reduce((total, cube) => total + cube.volume, 0)}
|
214
|
+
+ </td>
|
215
|
+
</tr>
|
216
|
+
</tfoot>
|
217
|
+
</table>
|
218
|
+
```
|
219
|
+
|
220
|
+
|
221
|
+
```diff
|
222
|
+
</div>
|
223
|
+
);
|
224
|
+
}
|
225
|
+
-const Row = () => {
|
226
|
+
- const [vertical, setVertical] = useState(0);
|
227
|
+
- const [horizontal, setHorizontal] = useState(0);
|
228
|
+
- const [height, setHeight] = useState(0);
|
229
|
+
- const onChangeVertical = (event) => {
|
230
|
+
- setVertical(event.target.value);
|
231
|
+
- };
|
232
|
+
- const onChangeHorizontal = (event) => {
|
233
|
+
- setHorizontal(event.target.value);
|
234
|
+
- };
|
235
|
+
- const onChangeHeight = (event) => {
|
236
|
+
- setHeight(event.target.value);
|
237
|
+
- };
|
238
|
+
- const volume = vertical * horizontal * height;
|
239
|
+
+const Row = ({ cube, onChange }) => {
|
240
|
+
+ const handleChange = useCallback(
|
241
|
+
+ (name, size) => {
|
242
|
+
+ onChange(name, size);
|
243
|
+
+ },
|
244
|
+
+ [onChange]
|
245
|
+
+ );
|
246
|
+
+
|
247
|
+
return (
|
248
|
+
<tr>
|
249
|
+
- <td>
|
250
|
+
- <input
|
251
|
+
- type="number"
|
252
|
+
- value={vertical}
|
253
|
+
- onChange={onChangeVertical}
|
254
|
+
- className="rounded border-2 p-1 w-20 text-right"
|
255
|
+
- />
|
256
|
+
- </td>
|
257
|
+
- <td>
|
258
|
+
- <input
|
259
|
+
- type="number"
|
260
|
+
- value={horizontal}
|
261
|
+
- onChange={onChangeHorizontal}
|
262
|
+
- className="rounded border-2 p-1 w-20 text-right"
|
263
|
+
- />
|
264
|
+
- </td>
|
265
|
+
- <td>
|
266
|
+
- <input
|
267
|
+
- type="number"
|
268
|
+
- value={height}
|
269
|
+
- onChange={onChangeHeight}
|
270
|
+
- className="rounded border-2 p-1 w-20 text-right"
|
271
|
+
- />
|
272
|
+
- </td>
|
273
|
+
- <td className="text-right">{volume}</td>
|
274
|
+
+ {["vertical", "horizontal", "height"].map((name) => (
|
275
|
+
+ <td key={name}>
|
276
|
+
+ <input
|
277
|
+
+ type="number"
|
278
|
+
+ value={cube[name]}
|
279
|
+
+ onChange={(e) => handleChange(name, e.target.valueAsNumber)}
|
280
|
+
+ className="rounded border-2 p-1 w-20 text-right"
|
281
|
+
+ />
|
282
|
+
+ </td>
|
283
|
+
+ ))}
|
284
|
+
+ <td className="text-right">{cube.volume}</td>
|
285
|
+
</tr>
|
286
|
+
);
|
287
|
+
// useEffect(()=>{
|
288
|
+
|
289
|
+
```
|
290
|
+
|
291
|
+
- ご質問にある codesandbox を fork して上記の修正を反映したもの ???? [20211124-tablemultiple-forked-f3pqt](https://codesandbox.io/s/20211124-tablemultiple-forked-f3pqt?file=/src/App.js)
|