質問編集履歴
1
補足(背景)
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
|
+
```
|