Должны ли действия говорить с магазином?

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

var createAction = require('common/scripts/actions-helpers/create-action'),
    resource = require('common/scripts/resources/conversation');

module.exports = createAction(fetchAction);

function fetchAction(context, payload, success, failure) {
    resource.sync(context, payload.userId)
        .then(function(user) {
            context.dispatch('USER_FETCH', user);
            success();
        }, failure);
}

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

function getFetchedUser() {
    // <--------- HOW TO KNOW WHETHER USER FETCHED?
}

function fetchAction(context, payload, success, failure) {
    var user = getFetchedUser();
    if (user) {
        context.dispatch('USER_FETCH', user);
        success();
    } else {
        resource.sync(context, payload.userId)
            .then(function(user) {
                context.dispatch('USER_FETCH', user);
                success();
            }, failure);
    }
}

Проблема в том, что я не хочу управлять данными пользователей в действии, поэтому единственный способ, которым я могу реализовать getFetchedUser(), - это проверка в хранилище Users.
Это хороший подход?
Может ли действие получить доступ к магазину?

2 ответа

У меня тоже была похожая проблема. У меня есть PhotosStore, в котором все фотографии хранятся у пользователя, сервер отправляет их на страницы.

Пользователь может изменить порядок фотографий, добавив больше комментариев, больше просмотров. Является ли PhotosStore загружены все страницы, он может изменить порядок самостоятельно, если нет, необходимо вызвать сервер.

# actions
Actions.Photo = createActions(
  'sortBy', {'load': asyncResult: true}
)

# store
Store.Photos = Reflux.createStore(
  listenables: Actions.Photo

  onSortBy: (order) ->
    if @hasMorePages()
      Actions.Photo.load({order: order})
    else 
      # reorder and trigger

  onLoadCompleted: (data) ->
    # get data and trigger
)

# view
PhotoHeaderOrder = React.createClass
  mixins: [
    Reflux.connect(Store.Photos, 'model')
  ]

  onSortNew: -> Actions.Photo.sortBy('news')
  onSortCom: -> Actions.Photo.sortBy('comments')
  onSortVie: -> Actions.Photo.sortBy('views')

  render: ->
    # render code

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

var AppDispatcher = require(<Flux AppDispatcher>);
var UserActions = {

  fetchUser: function(payload) {
     fetchUserFromBackendApi(payload)
     .then(function (error, user) {
        if(error) {
           AppDispatcher.dispatch({
              actionType: "ERROR_CODE",
              error: error
          });
          return;
        }
       AppDispatcher.dispatch({
          actionType: "SUCCESSFUL_USER",
          user: user
       });
     }
  }
};

module.exports = UserActions;

Затем вы просто обрабатываете различные типы действий в магазине и просто заполняете кеш. Когда кеш заполнен, вы генерируете событие изменения, и данные будут отображаться в.

Этот код не самый красивый, так что кричите, если я неправильно понял или есть какие-либо вопросы.

Так что ответить на первоначальный ответ. Компонент действия не должен общаться с магазином. Это идет вразрез с одним из ключевых понятий React, слабой связью. С Flux и React поток данных работает, потому что компоненты запускают действия, когда им нужны данные. Действия просто получают данные.

Другие вопросы по тегам