回答編集履歴

3

テキスト追加

2021/11/28 23:59

投稿

退会済みユーザー
test CHANGED
@@ -262,7 +262,7 @@
262
262
 
263
263
  ```
264
264
 
265
- 上記のクラス`Cube` は、質問にあるコードにある`class Rectangular` と同様のものです。以下はこのクラスを使った場合の修正箇所です。
265
+ 上記のクラス`Cube` は、質問に添付のコードに含まれていた`class Rectangular` と同様のものです。以下はこのクラスを使った場合の修正箇所です。
266
266
 
267
267
 
268
268
 

2

テキスト追加

2021/11/28 23:59

投稿

退会済みユーザー
test CHANGED
@@ -262,9 +262,7 @@
262
262
 
263
263
  ```
264
264
 
265
-
266
-
267
- 以下は上記の`Cude`クラスを使った場合の修正箇所です。
265
+ 上記のクラス`Cube` は、質問にあるコードにある`class Rectangular` と同様のものです。以下はこのクラスを使った場合の修正箇所です。
268
266
 
269
267
 
270
268
 

1

テキスト追加

2021/11/28 23:45

投稿

退会済みユーザー
test CHANGED
@@ -225,3 +225,357 @@
225
225
 
226
226
 
227
227
  - ご質問にある codesandbox を fork して上記の修正を反映したもの ???? [20211124-tablemultiple-forked-1vh3h](https://codesandbox.io/s/20211124-tablemultiple-forked-1vh3h?file=/src/App.js)
228
+
229
+
230
+
231
+
232
+
233
+ ### 別案
234
+
235
+
236
+
237
+ stateを見直すことは同じですが、各直方体の3辺の情報自体を、Appのstate として持つというのもありかと思います。たとえば、以下のようなクラスを作り、これのインスタンスの配列 `cubes` を stateに持たせます。
238
+
239
+ ```javascript
240
+
241
+ class Cube {
242
+
243
+ constructor(otherCube) {
244
+
245
+ this.vertical = otherCube ? otherCube.vertical : 0;
246
+
247
+ this.horizontal = otherCube ? otherCube.horizontal : 0;
248
+
249
+ this.height = otherCube ? otherCube.height : 0;
250
+
251
+ }
252
+
253
+
254
+
255
+ get volume() {
256
+
257
+ return this.vertical * this.horizontal * this.height;
258
+
259
+ }
260
+
261
+ }
262
+
263
+ ```
264
+
265
+
266
+
267
+ 以下は上記の`Cude`クラスを使った場合の修正箇所です。
268
+
269
+
270
+
271
+ ```diff
272
+
273
+ import "./styles.css";
274
+
275
+ -import { useState, useEffect } from "react";
276
+
277
+ -// import { Cube } from "./components/Cube";
278
+
279
+ +import { useState, useCallback } from "react";
280
+
281
+ +
282
+
283
+ +class Cube {
284
+
285
+ + constructor(otherCube) {
286
+
287
+ + this.vertical = otherCube ? otherCube.vertical : 0;
288
+
289
+ + this.horizontal = otherCube ? otherCube.horizontal : 0;
290
+
291
+ + this.height = otherCube ? otherCube.height : 0;
292
+
293
+ + }
294
+
295
+ +
296
+
297
+ + get volume() {
298
+
299
+ + return this.vertical * this.horizontal * this.height;
300
+
301
+ + }
302
+
303
+ +}
304
+
305
+
306
+
307
+ export default function App() {
308
+
309
+ - const [numberOfCubes, setNumberOfCubes] = useState(1);
310
+
311
+ - const [total, setTotal] = useState(0);
312
+
313
+ + const [cubes, setCubes] = useState([new Cube()]);
314
+
315
+ +
316
+
317
+ const decreaseCubes = () => {
318
+
319
+ - if (numberOfCubes === 0) return;
320
+
321
+ - setNumberOfCubes(numberOfCubes - 1);
322
+
323
+ + if (cubes.length === 0) return;
324
+
325
+ + setCubes(cubes.slice(0, cubes.length - 1));
326
+
327
+ };
328
+
329
+ +
330
+
331
+ const increaseCubes = () => {
332
+
333
+ - setNumberOfCubes(numberOfCubes + 1);
334
+
335
+ + setCubes([...cubes, new Cube()]);
336
+
337
+ };
338
+
339
+
340
+
341
+ + const handleChangeCube = useCallback(
342
+
343
+ + (selectedIndex, name, size) => {
344
+
345
+ + setCubes(
346
+
347
+ + cubes.map((cube, i) => {
348
+
349
+ + if (i === selectedIndex) {
350
+
351
+ + const newCube = new Cube(cube);
352
+
353
+ + newCube[name] = size;
354
+
355
+ + return newCube;
356
+
357
+ + }
358
+
359
+ + return cube;
360
+
361
+ + })
362
+
363
+ + );
364
+
365
+ + },
366
+
367
+ + [cubes]
368
+
369
+ + );
370
+
371
+ +
372
+
373
+ return (
374
+
375
+ <div className="App">
376
+
377
+ <table className="table-auto my-10">
378
+
379
+
380
+
381
+ ```
382
+
383
+
384
+
385
+
386
+
387
+ ```diff
388
+
389
+ </tr>
390
+
391
+ </thead>
392
+
393
+ <tbody>
394
+
395
+ - {[...(Array(numberOfCubes) || 0)].map((key) => (
396
+
397
+ - <Row key={key} />
398
+
399
+ + {cubes.map((cube, i) => (
400
+
401
+ + <Row
402
+
403
+ + key={`cube-${i}`}
404
+
405
+ + cube={cube}
406
+
407
+ + onChange={(name, size) => handleChangeCube(i, name, size)}
408
+
409
+ + />
410
+
411
+ ))}
412
+
413
+ </tbody>
414
+
415
+ <tfoot>
416
+
417
+ <tr>
418
+
419
+ <th colSpan="3">計</th>
420
+
421
+ - <td className="text-right">{total}</td>
422
+
423
+ + <td className="text-right">
424
+
425
+ + {cubes.reduce((total, cube) => total + cube.volume, 0)}
426
+
427
+ + </td>
428
+
429
+ </tr>
430
+
431
+ </tfoot>
432
+
433
+ </table>
434
+
435
+ ```
436
+
437
+
438
+
439
+
440
+
441
+ ```diff
442
+
443
+ </div>
444
+
445
+ );
446
+
447
+ }
448
+
449
+ -const Row = () => {
450
+
451
+ - const [vertical, setVertical] = useState(0);
452
+
453
+ - const [horizontal, setHorizontal] = useState(0);
454
+
455
+ - const [height, setHeight] = useState(0);
456
+
457
+ - const onChangeVertical = (event) => {
458
+
459
+ - setVertical(event.target.value);
460
+
461
+ - };
462
+
463
+ - const onChangeHorizontal = (event) => {
464
+
465
+ - setHorizontal(event.target.value);
466
+
467
+ - };
468
+
469
+ - const onChangeHeight = (event) => {
470
+
471
+ - setHeight(event.target.value);
472
+
473
+ - };
474
+
475
+ - const volume = vertical * horizontal * height;
476
+
477
+ +const Row = ({ cube, onChange }) => {
478
+
479
+ + const handleChange = useCallback(
480
+
481
+ + (name, size) => {
482
+
483
+ + onChange(name, size);
484
+
485
+ + },
486
+
487
+ + [onChange]
488
+
489
+ + );
490
+
491
+ +
492
+
493
+ return (
494
+
495
+ <tr>
496
+
497
+ - <td>
498
+
499
+ - <input
500
+
501
+ - type="number"
502
+
503
+ - value={vertical}
504
+
505
+ - onChange={onChangeVertical}
506
+
507
+ - className="rounded border-2 p-1 w-20 text-right"
508
+
509
+ - />
510
+
511
+ - </td>
512
+
513
+ - <td>
514
+
515
+ - <input
516
+
517
+ - type="number"
518
+
519
+ - value={horizontal}
520
+
521
+ - onChange={onChangeHorizontal}
522
+
523
+ - className="rounded border-2 p-1 w-20 text-right"
524
+
525
+ - />
526
+
527
+ - </td>
528
+
529
+ - <td>
530
+
531
+ - <input
532
+
533
+ - type="number"
534
+
535
+ - value={height}
536
+
537
+ - onChange={onChangeHeight}
538
+
539
+ - className="rounded border-2 p-1 w-20 text-right"
540
+
541
+ - />
542
+
543
+ - </td>
544
+
545
+ - <td className="text-right">{volume}</td>
546
+
547
+ + {["vertical", "horizontal", "height"].map((name) => (
548
+
549
+ + <td key={name}>
550
+
551
+ + <input
552
+
553
+ + type="number"
554
+
555
+ + value={cube[name]}
556
+
557
+ + onChange={(e) => handleChange(name, e.target.valueAsNumber)}
558
+
559
+ + className="rounded border-2 p-1 w-20 text-right"
560
+
561
+ + />
562
+
563
+ + </td>
564
+
565
+ + ))}
566
+
567
+ + <td className="text-right">{cube.volume}</td>
568
+
569
+ </tr>
570
+
571
+ );
572
+
573
+ // useEffect(()=>{
574
+
575
+
576
+
577
+ ```
578
+
579
+
580
+
581
+ - ご質問にある codesandbox を fork して上記の修正を反映したもの ???? [20211124-tablemultiple-forked-f3pqt](https://codesandbox.io/s/20211124-tablemultiple-forked-f3pqt?file=/src/App.js)