質問編集履歴

1

補足(背景)

2020/09/19 19:53

投稿

ytt451
ytt451

スコア6

test CHANGED
File without changes
test CHANGED
@@ -291,3 +291,201 @@
291
291
  `shopItem.quantity`に何かを代入された要因がどうしても分かりません。
292
292
 
293
293
  教えていただけると嬉しいです。
294
+
295
+
296
+
297
+ # 補足(背景)
298
+
299
+
300
+
301
+ 元はReactのコードなのですが、state更新が予想と違い
302
+
303
+ JavaScriptだけ抜き出したところ、生JSの部分が分からないと判断した経緯があります。
304
+
305
+
306
+
307
+ 原型のコードは以下のようになります。
308
+
309
+
310
+
311
+ ```tsx
312
+
313
+ import React from 'react';
314
+
315
+ import './tailwind.output.css';
316
+
317
+
318
+
319
+ type Product = { id: number; title: string; price: number; quantity: number };
320
+
321
+
322
+
323
+ type Products = Product[];
324
+
325
+
326
+
327
+ const products: Products = [
328
+
329
+ { id: 1, title: '商品1', price: 100, quantity: 1 },
330
+
331
+ { id: 2, title: '商品2', price: 150, quantity: 1 },
332
+
333
+ { id: 3, title: '商品3', price: 200, quantity: 1 },
334
+
335
+ { id: 4, title: '商品4', price: 250, quantity: 1 },
336
+
337
+ { id: 5, title: '商品5', price: 300, quantity: 1 },
338
+
339
+ ];
340
+
341
+
342
+
343
+ type SampleProps = {};
344
+
345
+
346
+
347
+ type SampleCartState = { shopItems: Products; cartItems: Products };
348
+
349
+
350
+
351
+ class Sample extends React.Component<SampleProps, SampleCartState> {
352
+
353
+ constructor(props: Readonly<SampleProps>) {
354
+
355
+ super(props);
356
+
357
+ this.state = { shopItems: products, cartItems: [] };
358
+
359
+ this.addToCart = this.addToCart.bind(this);
360
+
361
+ }
362
+
363
+
364
+
365
+ addToCart(shopItem: Product) {
366
+
367
+ let isShopItemInCart: boolean = false;
368
+
369
+ const cartItems: Products = [...this.state.cartItems];
370
+
371
+
372
+
373
+ cartItems.forEach((cartItem) => {
374
+
375
+ if (cartItem.id === shopItem.id) {
376
+
377
+ isShopItemInCart = true;
378
+
379
+ cartItem.quantity = Number(cartItem.quantity + shopItem.quantity);
380
+
381
+ }
382
+
383
+ });
384
+
385
+
386
+
387
+ this.setState({ cartItems: cartItems });
388
+
389
+
390
+
391
+ if (!isShopItemInCart) {
392
+
393
+ this.setState({ cartItems: [...cartItems, shopItem] });
394
+
395
+ }
396
+
397
+ }
398
+
399
+
400
+
401
+ getTotalPrice() {
402
+
403
+ let totalPrice: number = 0;
404
+
405
+ this.state.cartItems.forEach((cartItem) => {
406
+
407
+ totalPrice = totalPrice + cartItem.price * cartItem.quantity;
408
+
409
+ });
410
+
411
+ return totalPrice;
412
+
413
+ }
414
+
415
+
416
+
417
+ render() {
418
+
419
+ return (
420
+
421
+ <div>
422
+
423
+ {/* 商品一覧 */}
424
+
425
+ <h2 className="text-3xl">商品一覧</h2>
426
+
427
+ {this.state.shopItems.map((shopItem) => (
428
+
429
+ <div key={shopItem.id}>
430
+
431
+ {shopItem.title} {shopItem.price}円 × {shopItem.quantity}個{' '}
432
+
433
+ <button
434
+
435
+ className="bg-gray-400"
436
+
437
+ onClick={() => this.addToCart(shopItem)}
438
+
439
+ >
440
+
441
+ 追加
442
+
443
+ </button>
444
+
445
+ </div>
446
+
447
+ ))}
448
+
449
+
450
+
451
+ {/* カート */}
452
+
453
+ <h2 className="text-3xl">カート (計 {this.getTotalPrice()}円)</h2>
454
+
455
+ {this.state.cartItems.map((cartItem) => (
456
+
457
+ <div key={cartItem.id}>
458
+
459
+ {cartItem.title} {cartItem.price}円 × {cartItem.quantity}個
460
+
461
+ </div>
462
+
463
+ ))}
464
+
465
+ </div>
466
+
467
+ );
468
+
469
+ }
470
+
471
+ }
472
+
473
+
474
+
475
+ export default function App() {
476
+
477
+ return (
478
+
479
+ <div className="container mx-auto px-4">
480
+
481
+ <Sample />
482
+
483
+ </div>
484
+
485
+ );
486
+
487
+ }
488
+
489
+
490
+
491
+ ```