2015-03-12 2 views
0

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

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() проверяет в магазине пользователей ,
Это хороший подход?
Можно ли получить доступ к хранилищу?

ответ

0

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

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 поток данных работает, потому что компоненты будут запускать действия, когда им нужны данные. Действия просто извлекают данные.

+0

Это не ответит на вопрос, так как он сделает внутренний вызов, даже если данные уже существуют в магазине или нет. –

+0

Нужно ли проверять, был ли пользователь, которого я дважды набирал? Если вы выберете пользователя, вы можете исправить это изменение и отправить пользовательские данные соответствующему компоненту. Часто ли нужны данные для обновления? Вы не должны сообщать об этом прямо в магазин. Эта свободная связь является одной из ключевых концепций React. Часто компоненты и реквизиты компонентов определяют, получили ли они правильные данные, а затем запускают действия по их сбору. – magnudae

+0

Ой не видел, что ты не был аскером. Вы можете игнорировать первый вопрос в моем комментарии. – magnudae

0

У меня также была аналогичная проблема. У меня есть ФотоСпорт, который держит все фотографии от пользователя, сервер отправляет его разбитым на страницы.

Пользователь может изменить порядок фотографий совсем недавно, более комментируемым, более просматриваемым. Является ли 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 
+0

В случае, если я понял ваш код, вы вызываете действие из своего магазина? Это хороший подход или взлом? – Naor

Смежные вопросы