teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

補足(背景)

2020/09/19 19:53

投稿

ytt451
ytt451

スコア6

title CHANGED
File without changes
body CHANGED
@@ -144,4 +144,103 @@
144
144
  # 疑問点
145
145
 
146
146
  `shopItem.quantity`に何かを代入された要因がどうしても分かりません。
147
- 教えていただけると嬉しいです。
147
+ 教えていただけると嬉しいです。
148
+
149
+ # 補足(背景)
150
+
151
+ 元はReactのコードなのですが、state更新が予想と違い
152
+ JavaScriptだけ抜き出したところ、生JSの部分が分からないと判断した経緯があります。
153
+
154
+ 原型のコードは以下のようになります。
155
+
156
+ ```tsx
157
+ import React from 'react';
158
+ import './tailwind.output.css';
159
+
160
+ type Product = { id: number; title: string; price: number; quantity: number };
161
+
162
+ type Products = Product[];
163
+
164
+ const products: Products = [
165
+ { id: 1, title: '商品1', price: 100, quantity: 1 },
166
+ { id: 2, title: '商品2', price: 150, quantity: 1 },
167
+ { id: 3, title: '商品3', price: 200, quantity: 1 },
168
+ { id: 4, title: '商品4', price: 250, quantity: 1 },
169
+ { id: 5, title: '商品5', price: 300, quantity: 1 },
170
+ ];
171
+
172
+ type SampleProps = {};
173
+
174
+ type SampleCartState = { shopItems: Products; cartItems: Products };
175
+
176
+ class Sample extends React.Component<SampleProps, SampleCartState> {
177
+ constructor(props: Readonly<SampleProps>) {
178
+ super(props);
179
+ this.state = { shopItems: products, cartItems: [] };
180
+ this.addToCart = this.addToCart.bind(this);
181
+ }
182
+
183
+ addToCart(shopItem: Product) {
184
+ let isShopItemInCart: boolean = false;
185
+ const cartItems: Products = [...this.state.cartItems];
186
+
187
+ cartItems.forEach((cartItem) => {
188
+ if (cartItem.id === shopItem.id) {
189
+ isShopItemInCart = true;
190
+ cartItem.quantity = Number(cartItem.quantity + shopItem.quantity);
191
+ }
192
+ });
193
+
194
+ this.setState({ cartItems: cartItems });
195
+
196
+ if (!isShopItemInCart) {
197
+ this.setState({ cartItems: [...cartItems, shopItem] });
198
+ }
199
+ }
200
+
201
+ getTotalPrice() {
202
+ let totalPrice: number = 0;
203
+ this.state.cartItems.forEach((cartItem) => {
204
+ totalPrice = totalPrice + cartItem.price * cartItem.quantity;
205
+ });
206
+ return totalPrice;
207
+ }
208
+
209
+ render() {
210
+ return (
211
+ <div>
212
+ {/* 商品一覧 */}
213
+ <h2 className="text-3xl">商品一覧</h2>
214
+ {this.state.shopItems.map((shopItem) => (
215
+ <div key={shopItem.id}>
216
+ {shopItem.title} {shopItem.price}円 × {shopItem.quantity}個{' '}
217
+ <button
218
+ className="bg-gray-400"
219
+ onClick={() => this.addToCart(shopItem)}
220
+ >
221
+ 追加
222
+ </button>
223
+ </div>
224
+ ))}
225
+
226
+ {/* カート */}
227
+ <h2 className="text-3xl">カート (計 {this.getTotalPrice()}円)</h2>
228
+ {this.state.cartItems.map((cartItem) => (
229
+ <div key={cartItem.id}>
230
+ {cartItem.title} {cartItem.price}円 × {cartItem.quantity}個
231
+ </div>
232
+ ))}
233
+ </div>
234
+ );
235
+ }
236
+ }
237
+
238
+ export default function App() {
239
+ return (
240
+ <div className="container mx-auto px-4">
241
+ <Sample />
242
+ </div>
243
+ );
244
+ }
245
+
246
+ ```