【问题标题】:Mobx State Tree reference type and TypescriptMobx 状态树引用类型和 Typescript
【发布时间】:2021-05-03 14:47:22
【问题描述】:

我在 React 应用程序中使用 mobx-state-tree 和 Typescript。而且,我遇到了 Typescript 的问题,它抱怨 mobx 类型 types.safeReference 的类型。看起来模型定义中safeReference 的类型与使用.create() 实际创建模型实例时的类型不同。在我的代码中,selectedProduct 的类型在productStore 中转换为string | number | undefined | null,但在模型定义中是IStateTreeNode<...> | undefined | null,这就是我在根存储中出现错误的原因。我该如何解决?

这是我的产品商店:

import { types } from "mobx-state-tree";

const Product = types.model("Product", {
   id: types.identifier,
   name: types.string
})

const ProductStore = types
  .model("ProductStore", {
    products: types.array(Product),
    selectedProduct: types.safeReference(Product),
  })
  .actions((self) => ({
      // actions here
  }));

export const productStore = ProductStore.create({
  products: [],
  selectedProduct: undefined // the type here is different from the type in the actual model
});

还有,这是我的根存储:

import { types } from "mobx-state-tree";
import ProductStore, { productStore } from "./product-store";

const RootStore = types.model('RootStore', {    
  productStore: ProductStore 
})

export const rootStore = RootStore.create({
    productStore: productStore // Here is where I get the typescript error.
});

更新:

重现此问题的另一种方法是尝试创建自定义引用。 getter 会抱怨 undefined 不能分配给类型 {...}。

const ProductByIdReference = types.maybeNull(
  types.reference(Product, {
      get(id: number, parent: Instance<typeof ProductStore>) {
          return parent.products.find(p => p.id === id) || undefined
      },
      set(value: Instance<typeof Product>) {
          return value.id
      }
  })
)

【问题讨论】:

  • 我不确定这是疏忽还是预期的行为,非常有趣。与其导出ProductStore 单例,不如让RootStore 为您创建它吗? IE。 export const rootStore = RootStore.create({ productStore: { products: [], selectedProduct: undefined } });
  • 不,必须是单例的。
  • 这是不是一切正常而只是TS错误的情况?似乎RootStore.create 正在寻找原始价值而不是创建的商店。如果您将productStore 的初始状态而不是商店本身传递给它,那么它可以正常工作。不确定这是否有用,但这个答案显示了一种非常不同的方式来合并商店:stackoverflow.com/a/54081439/10431574
  • 有很多实用程序类型在起作用github.com/mobxjs/mobx-state-tree/blob/… 但错误链中的最低消息是您有一个IMSTArray github.com/mobxjs/mobx-state-tree/blob/… 并且它需要一个实际的数组。它抱怨IMSTArray 没有数组应有的所有方法。
  • 谢谢@LindaPaiste,抱歉耽搁了!我会试试看。

标签: reactjs typescript mobx mobx-react mobx-state-tree


【解决方案1】:

我详细检查了您的问题并编写了解决方案,这是如何正确使用mst rootStore 概念,无需创建您的商店或对象的实例,只需@inject 直接在组件内部:

// Product Store
import { types, Instance } from "mobx-state-tree";

const Product = types.model("Product", {
  id: types.identifier,
  name: types.string
})

const Store = types
  .model("ProductStore", {
    products: types.array(Product),
    selectedProduct: types.safeReference(Product),
  })
  .actions((self) => ({
    // actions here
  }));

type ProductStoreType = typeof Store;
interface ProductStoreTypeInterface extends ProductStoreType {}
export interface ProductStoreInterface extends Instance<ProductStoreTypeInterface> {}
export const ProductStore: ProductStoreTypeInterface = Store;

// Root Store
import { types } from "mobx-state-tree";
import { ProductStore } from "./product-store";

const RootStore = types.model('RootStore', {
  productStore: types.late(() => types.optional(ProductStore, {})),
})

// And now you can create rootStore with empty object
export const rootStore = RootStore.create({});

// Component
import { inject, observer } from 'mobx-react';
import { SettingStoreInterface } from "../settings/SettingStore";
import React from "react";

interface ComponentProps {}

interface InjectedProps extends ComponentProps {
  productStore: ProductStoreInterface;
}

@inject('productStore')
@observer
class SomeComponent extends React.Component<ComponentProps> {
  componentDidMount() {
    const { productStore } = this.props as InjectedProps;
    
    console.log(productStore.products);
  }
}

【讨论】:

  • 但是,您不是在创建 Product Store。
  • 它会在你注入组件时创建
  • 这行不通。产品商店尚未创建,无法注入。
  • 我的整个产品都是这样构建的,你至少需要测试一下,然后再写它不起作用
  • 我会试一试,但无论如何,这个解决方案对我不起作用,因为我正在使用反应钩子。我需要能够使用useContext 使用商店。
【解决方案2】:

一般来说,当您尝试使用通常使用实例的快照时,您使用cast。当您尝试使用通常使用快照的实例时,请使用castToSnapshot

export const rootStore = RootStore.create({
    productStore: castToSnapshot(productStore)
});

【讨论】:

    猜你喜欢
    • 2019-02-12
    • 2021-05-09
    • 2019-07-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多