微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 MobX 中使用 Set() 和 TypeScript?

如何解决在 MobX 中使用 Set() 和 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.tsThe docs 没有完整的例子。我该怎么做?

Stackblitz 复制 → https://stackblitz.com/edit/react-mobx-set-not-working?file=store.ts

解决方法

我使用了 Map 而不是 Set,但是如果您想用 Map 替换 Set,它也可以完美运行。

我使用带有 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'));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。