【问题标题】:Use Set() in MobX with TypeScript?在 MobX 中使用 Set() 和 TypeScript?
【发布时间】:2021-08-15 17:36:30
【问题描述】:

我有一个简单的 Grocery Shopping 应用程序,我想在其中使用 Set(),但是当我尝试使用 Set() 时出现各种错误。我正在使用 MobX 和 TypeScript。

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

【问题讨论】:

  • 所以我有 2 个问题,你已经尝试过什么以及你遇到了什么样的错误?另外,你为什么要对buyer 使用 Set 呢? Set 就像一个数组,而您的应用程序中的buyer 是一个带有字段的对象,您如何将cash 存储在一个Set 中?
  • @Danila 我尝试在types.ts 中执行new Set&lt;Buyer&gt;(),因为我认为我还需要更改types 文件。它给出了一个错误'(' expected.(1005)。是的,我想我需要将items 设置为Set(),因为我想在使用buyItem 购买物品时存储物品的name,例如Egg 并增加quantity,这样就解决了一半的问题。我刚刚阅读了Set 文档,它确实显示可以使用对象。但是知道如何在 MobX 中使用 Set 仍然会有所帮助吗?
  • 我还是不明白为什么你甚至需要在这里设置?如果您希望买家物品成为套装,那么这里是 stackblitz.com/edit/…,但在我看来,几乎没有理由将其设为套装
  • @Danila 你是对的。我希望它像字典一样,但后来意识到我必须保持items 独特和quantity 不断增加,所以我想到了Set。最终,我只是选择了map,并检查了.has(),只保留独特的物品。

标签: javascript typescript set mobx mobx-react


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2021-04-05
    • 2023-03-11
    • 2021-02-10
    • 2020-04-03
    • 2020-12-22
    • 1970-01-01
    相关资源
    最近更新 更多