Использование действий react mobx из других хранилищ внутри компонентов и других хранилищ

#javascript #reactjs #native #mobx

#javascript #reactjs #родной #mobx

Вопрос:

в моем приложении react native я хочу использовать mobx для управления состоянием, мой магазин разделен на несколько хранилищ / файлов, и поскольку я хочу иметь возможность вызывать действия магазина из других магазинов, я реализую GlobalStore, где я создаю экземпляры других магазинов.

Я хочу иметь возможность делать что-то подобное из своих компонентов

 import { PostStore }  from '../stores/PostStore.js'
import { UserStore }  from '../stores/UserStore.js'
import { VenueStore }  from '../stores/VenueStore.js'


class GlobalStore
{
    
    postStore = new PostStore(this);
    userStore = new UserStore(this);
    venueStore = new VenueStore(this);

}

export default new GlobalStore;
  

Это позволяет использовать API-интерфейс контекстного провайдера react-native, я могу вызывать каждое действие хранилища во ВСЕХ моих компонентах, используя globalStore в качестве ссылки:

В любом компоненте я могу сделать:

 globalStore.postStore.listPosts()
  

Однако я все еще не уверен, как я могу получить доступ к другим действиям магазина из ДРУГИХ МАГАЗИНОВ.

Что делать, если внутри PostStore я хочу использовать spinnerStore (для отображения ожидающих вызовов axios, статуса ошибки или успеха):

 @action.bound getPosts = flow(function * (payload) 
    {
        this.spinnerStore.setData({status: 1});
        try 
        {
            this.spinnerStore.setData({status: 2, response: response});
            let response = yield axios.get('/api/posts', { params: payload })
            return response;
        } 
        catch (error) {
            console.error(error);
            this.spinnerStore.setData({ status: 3, errors: error });
            throw error;
        }
    })
  

Здесь spinnerStore будет неопределенным…

Ответ №1:

Однако я все еще не уверен, как я могу получить доступ к другим действиям магазина из ДРУГИХ МАГАЗИНОВ.

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

 class Foo {
  constructor(instance) {
    this.instance = instance
  }
}

class Bar {}

const foo = new Foo(new Bar());

foo.instance instanceof Bar; // true
  

Теперь ваш foo экземпляр имеет доступ к любым общедоступным свойствам / методам, определенным на Bar

 class Foo {
  constructor(instance) {
    this.instance = instance
  }
}

class Bar {
  @observable isLoading = false;
  @observable data = null;

  @action
  getData() {
    this.isLoading = true;
    return axios.get('/foo').then((data) => {
      this.isLoading = false;
      this.data = data;
    }).catch(e => {
      this.isLoading = false;
    });
  }
}

const foo = new Foo(new Bar());

// in react
const MyComponent = ({ foo }) => (
  <div>
    {foo.instance.isLoading amp;amp; <Spinner />}

    <button onClick={foo.instance.getData}>
     will call Bar action from Foo store
    </button>
  </div>
);

export default lodash.flowRight(
  mobx.inject((stores) => ({ foo: stores.fooStore })),
  mobx.observer
)(MyComponent)
  

В вашем примере с генераторами вы не можете использовать жирные стрелки, поэтому this он больше не привязан к вашему экземпляру класса, поэтому он будет неопределенным. Использование обещаний и жирных стрелок решает эту проблему.