Обновление хранилища mobx, наблюдаемого внутри себя, приводит к «Не удается прочитать свойство <observable>из неопределенного» - PullRequest
1 голос
/ 25 января 2020

Я знаю, что несколько подобных проблем уже существуют. Однако, просмотрев многие из них, я не смог найти решение своей проблемы. Вот ситуация:

Я хочу, чтобы мой ReportStore извлекал данные с сервера в виде массива и сохранял их на наблюдаемой карте. Выборка в порядке, данные поступают правильно. Проблема возникает, когда я пытаюсь записать значения в наблюдаемую карту внутри метода requestNewReports. Вот код магазина:

ReportStore.ts

import api from "../api";
import { observable, action, ObservableMap } from "mobx";
import { IReportMetaData } from "../pages/ManagerView/TicketSales";
import { notificationStore } from "./NotificationStore";

export class ReportStore {
  fetchedReports: ObservableMap<number, IReportMetaData>;

  constructor() {
    this.fetchedReports = observable.map({});
  }

  async requestNewReports(fromDate: string = '', toDate: string = '') {
    try {
      const res = await api.get("reports/filtered", {
        params: {
          fromDate: from,
          toDate: to
        }
      });
      res.data.forEach((row: IReportMetaData, index: number) => {
        if (!this.fetchedReports.has(index)) {
          this.fetchedReports.set(index, row);
        }
      });
    } catch (err) {
      return notificationStore.showError(err.message);
    }
  }
}

export const reportStore = new ReportStore();

Хранилище предоставляется в app.tsx через <Provider reportStore={reportStore}>....</Provider> и вводится в такие компоненты, как этот :

export interface ITicketSalesProps {
  reportStore?: ReportStore;
}


export const TicketSales = inject('reportStore')(observer((props: ITicketSalesProps) => {
   // Component logic
}

И меня так называют:

// inside TicketSales
useEffect(() => {
  const { fetchedReports, requestNewReports } = props.reportStore!;
    if (fetchedReports.size === 0) {
      requestNewReports();
    }
  }, []);

Моя настройка: create-react-app через npx с TypeScript,

"mobx": "^5.15.3",
"mobx-react": "^6.1.4",

По некоторым вопросам проблема заключается в устаревших декораторах. Однако в соответствии с официальной mobx документацией

Декораторы поддерживаются только из коробки при использовании TypeScript в create-react-app@^2.1.1. В более старых версиях или при использовании vanilla JavaScript используйте либо утилиту decorate, либо eject, либо пакет customize-cra.

Что, по-видимому, и является моим случаем.

Следовательно, я У меня нет идей, почему его можно сломать ... Я даже пытался извлечь и попробовать плагин babel, как предлагалось в некоторых выпусках:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
  ]
}

Но безуспешно.

Любая помощь будет признателен.

Заранее спасибо!

1 Ответ

1 голос
/ 26 января 2020

Я думаю, что эта проблема связана с вашим javascript кодом в целом, а не с mobx.

Из того, что я могу прочитать здесь, requestNewReports() не является связанным методом . В вашем компоненте вы деструктурируете свой магазин и назначаете requestNewReports новой переменной, чтобы "this" больше не был вашим магазином. Таким образом, у вас есть «неопределенная» ошибка.

Вы можете изменить ее на:

// inside TicketSales
useEffect(() => {
  const {reportStore} = props
  if (reportStore.fetchedReports.size === 0) {
    reportStore.requestNewReports();
  }
}, []);

Или вы можете привязать метод к экземпляру, например:

...
  constructor() {
    this.fetchedReports = observable.map({});
    this.requestNewReports = this.requestNewReports.bind(this)
  }
...