Как объединить несколько магазинов в качестве корневого хранилища в Mobx и получить доступ к полям и функциям друг друга

#javascript #reactjs #typescript #mobx

Вопрос:

Я не знаю, как объединить два магазина в одном корневом магазине (используя Typescript). Например, у меня есть liveImageStore.ts (с методами, которые запрашивают изображение, также содержит массив URL-адресов последних 10 изображений) и notificationStore.ts (есть некоторая логика для установки/очистки уведомлений для дальнейшего использования во всем приложении. И запрос в liveImageStore.ts содержит некоторые ошибки (например, в случае проблем с подключением http). Я хотел бы вызвать функцию из notificationStore.ts (setNotification, которая отправляет в магазин новое уведомление) в методе запроса из первого магазина. Но как переслать и напечатать все это? Компонент уведомителя показывает сообщение, используя хранилище уведомлений.

Ответ №1:

Вот как я использую шаблон корневого хранилища:

 class RootStore {
  childStoreOne: ChildStoreOne
  childStoreTwo: ChildStoreTwo

  constructor() {
    this.childStoreOne = new ChildStoreOne(this)
    this.childStoreTwo = new ChildStoreTwo(this)
  }
}

class ChildStoreOne {
  root: RootStore
  constructor(root: RootStore) {
    this.root = root
  }
  methodOne() {}
}

class ChildStoreTwo {
  root: RootStore
  constructor(root: RootStore) {
    this.root = root
  }

  getSomethingFromStoreOne() {
    this.root.childStoreOne.methodOne()
  }
}
 

И это самая важная часть:

 // holds a reference to the store (singleton)
let store: RootStore

// create the context
const StoreContext = createContext<RootStore | undefined>(undefined);

// create the provider component
function RootStoreProvider({ children }: { children: ReactNode }) {
  //only create the store once ( store is a singleton)
  const root = store ?? new RootStore()

  return <StoreContext.Provider value={root}>{children}</StoreContext.Provider>
}

// create the hook
function useRootStore() {
  const context = useContext(StoreContext)
  if (context === undefined) {
    throw new Error("useRootStore must be used within RootStoreProvider")
  }

  return context
}
 

Просто убедитесь, что вы не обращаетесь к другим хранилищам в функциях конструктора, так как из-за порядка инициализации в этот момент может не быть создано какое-либо дочернее хранилище.

Я написал сообщение об этом шаблоне некоторое время назад: шаблон корневого хранилища Mobx с крючками react вы также найдете ссылку на демонстрационный проект с Nextjs.