在带有 TypeScript 的 MobX 中使用 Set()?
Use Set() in MobX with TypeScript?
我有一个简单的 Grocery Shopping 应用程序,我想在其中使用 Set()
,但是当我尝试使用 Set()
时遇到各种错误。我正在使用带有 TypeScript 的 MobX。
types.ts
export type Item = {
name: string;
instock: number;
price: number;
};
export type Buyer = {
cash: number;
items: Array<Pick<Item, 'name'> & { quantity: number }>;
};
export type IStore = {
items: Item[];
buyer: Buyer;
};
store.ts
import { observable, action, set, computed, makeObservable } from 'mobx';
import type { Item, IStore, Buyer } from './types';
export class Store implements IStore {
items: Item[] = [
{
name: "Egg",
instock: 30,
price: 4
},
{
name: "Apple",
instock: 24,
price: 20
},
{
name: "Banana",
instock: 60,
price: 8
}
]
buyer: Buyer = {
cash: 50,
items: [],
}
constructor() {
makeObservable(this, {
items: observable,
buyer: observable,
buyItem: action.bound,
});
}
buyItem(name: string, price: number, quantity: number) {
if (this.buyer.cash - price * quantity > 0) {
this.buyer.items.push({ name, quantity })
this.buyer.cash = this.buyer.cash - price * quantity
}
}
}
export const store = new Store();
我想将 buyer
设为 Set()
。例如,types.ts 应该将 buyer
变成:
.
.
.
export type IStore = {
.
.
.
buyer: new Set<Buyer>();
};
同样,我应该可以更改 store.ts
。 The docs 没有完整的示例。我该怎么做?
Stackblitz 再现 → https://stackblitz.com/edit/react-mobx-set-not-working?file=store.ts
我使用 Map
而不是 Set
,但是如果你想用 Set
替换 Map
,它也可以完美地工作。
我使用 Map
和 .has()
来检查存储的项目 name
是否是唯一的,因此它的行为类似于 Set
。
可以找到 Stackblitz → https://stackblitz.com/edit/react-mobx-grocery-shopping?file=index.tsx
types.ts
export type Item = {
name: string;
instock: number;
price: number;
};
export type BuyerItem = Pick<Item, 'name'> & { quantity: number };
export type Buyer = {
cash: number;
items: Map<string, number>;
};
export type IStore = {
items: Item[];
buyer: Buyer;
};
store.ts
import { observable, action, makeObservable } from 'mobx';
import type { Item, IStore, BuyerItem, Buyer } from './types';
export class Store implements IStore {
items: Item[] = [
{
name: "Egg",
instock: 30,
price: 4
},
{
name: "Apple",
instock: 24,
price: 20
},
{
name: "Banana",
instock: 60,
price: 8
}
]
buyer: Buyer = {
cash: 120,
items: new Map<string, number>(),
}
constructor() {
makeObservable(this, {
items: observable,
buyer: observable,
buyItem: action.bound,
});
}
buyItem(name: string, price: number, quantity: number) {
if (this.buyer.cash - price * quantity >= 0) {
if (this.buyer.items.has(name)) {
const alreadyBought = this.buyer.items.get(name)
this.buyer.items.set(name, quantity + alreadyBought)
}
else
this.buyer.items.set(name, quantity)
this.buyer.cash = this.buyer.cash - price * quantity
}
}
}
export const store = new Store();
index.tsx
import React, { Component } from 'react';
import { render } from 'react-dom';
import { observer } from "mobx-react";
import { useStore } from "./context";
const App = observer(() => {
const { items, buyer, buyItem } = useStore()
const buyerItems = Array.from(buyer.items)
return (
<div>
<h1>Grocery Shopping</h1>
<table style={{ width: 400, lineHeight: 2, border: "1px solid black", textAlign: "center" }}>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
<th>In Stock</th>
<th>Purchase</th>
</tr>
</thead>
<tbody>
{items.map(item => (
<tr key={item.name}>
<td>{item.name}</td>
<td>${item.price}</td>
<td>{item.instock}</td>
<td>
<button onClick={() => {
buyItem(item.name, item.price, 1)
}}>
Buy 1
</button>
</td>
</tr>
))}
</tbody>
</table>
<h2>${buyer.cash} balance left</h2>
{buyerItems.length > 0 && (
<>
<h2>Customer Bought:</h2>
<ul>
{buyerItems.map(item => {
return <li key={item[0]}>{item[1]} {item[0]}</li>
})}
</ul>
</>
)}
</div>
)
})
render(<App />, document.getElementById('root'));
我有一个简单的 Grocery Shopping 应用程序,我想在其中使用 Set()
,但是当我尝试使用 Set()
时遇到各种错误。我正在使用带有 TypeScript 的 MobX。
types.ts
export type Item = {
name: string;
instock: number;
price: number;
};
export type Buyer = {
cash: number;
items: Array<Pick<Item, 'name'> & { quantity: number }>;
};
export type IStore = {
items: Item[];
buyer: Buyer;
};
store.ts
import { observable, action, set, computed, makeObservable } from 'mobx';
import type { Item, IStore, Buyer } from './types';
export class Store implements IStore {
items: Item[] = [
{
name: "Egg",
instock: 30,
price: 4
},
{
name: "Apple",
instock: 24,
price: 20
},
{
name: "Banana",
instock: 60,
price: 8
}
]
buyer: Buyer = {
cash: 50,
items: [],
}
constructor() {
makeObservable(this, {
items: observable,
buyer: observable,
buyItem: action.bound,
});
}
buyItem(name: string, price: number, quantity: number) {
if (this.buyer.cash - price * quantity > 0) {
this.buyer.items.push({ name, quantity })
this.buyer.cash = this.buyer.cash - price * quantity
}
}
}
export const store = new Store();
我想将 buyer
设为 Set()
。例如,types.ts 应该将 buyer
变成:
.
.
.
export type IStore = {
.
.
.
buyer: new Set<Buyer>();
};
同样,我应该可以更改 store.ts
。 The docs 没有完整的示例。我该怎么做?
Stackblitz 再现 → https://stackblitz.com/edit/react-mobx-set-not-working?file=store.ts
我使用 Map
而不是 Set
,但是如果你想用 Set
替换 Map
,它也可以完美地工作。
我使用 Map
和 .has()
来检查存储的项目 name
是否是唯一的,因此它的行为类似于 Set
。
可以找到 Stackblitz → https://stackblitz.com/edit/react-mobx-grocery-shopping?file=index.tsx
types.ts
export type Item = {
name: string;
instock: number;
price: number;
};
export type BuyerItem = Pick<Item, 'name'> & { quantity: number };
export type Buyer = {
cash: number;
items: Map<string, number>;
};
export type IStore = {
items: Item[];
buyer: Buyer;
};
store.ts
import { observable, action, makeObservable } from 'mobx';
import type { Item, IStore, BuyerItem, Buyer } from './types';
export class Store implements IStore {
items: Item[] = [
{
name: "Egg",
instock: 30,
price: 4
},
{
name: "Apple",
instock: 24,
price: 20
},
{
name: "Banana",
instock: 60,
price: 8
}
]
buyer: Buyer = {
cash: 120,
items: new Map<string, number>(),
}
constructor() {
makeObservable(this, {
items: observable,
buyer: observable,
buyItem: action.bound,
});
}
buyItem(name: string, price: number, quantity: number) {
if (this.buyer.cash - price * quantity >= 0) {
if (this.buyer.items.has(name)) {
const alreadyBought = this.buyer.items.get(name)
this.buyer.items.set(name, quantity + alreadyBought)
}
else
this.buyer.items.set(name, quantity)
this.buyer.cash = this.buyer.cash - price * quantity
}
}
}
export const store = new Store();
index.tsx
import React, { Component } from 'react';
import { render } from 'react-dom';
import { observer } from "mobx-react";
import { useStore } from "./context";
const App = observer(() => {
const { items, buyer, buyItem } = useStore()
const buyerItems = Array.from(buyer.items)
return (
<div>
<h1>Grocery Shopping</h1>
<table style={{ width: 400, lineHeight: 2, border: "1px solid black", textAlign: "center" }}>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
<th>In Stock</th>
<th>Purchase</th>
</tr>
</thead>
<tbody>
{items.map(item => (
<tr key={item.name}>
<td>{item.name}</td>
<td>${item.price}</td>
<td>{item.instock}</td>
<td>
<button onClick={() => {
buyItem(item.name, item.price, 1)
}}>
Buy 1
</button>
</td>
</tr>
))}
</tbody>
</table>
<h2>${buyer.cash} balance left</h2>
{buyerItems.length > 0 && (
<>
<h2>Customer Bought:</h2>
<ul>
{buyerItems.map(item => {
return <li key={item[0]}>{item[1]} {item[0]}</li>
})}
</ul>
</>
)}
</div>
)
})
render(<App />, document.getElementById('root'));