【问题标题】:Should action talk with store?行动应该和店铺商谈吗?
【发布时间】:2015-05-14 13:08:46
【问题描述】:

我正在使用带有通量架构的反应,但我遇到了一个问题。
我需要创建一个获取用户 ID 并获取用户的操作。代码如下:

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() 的唯一方法是检查用户存储。
这是一个好方法吗?
可以操作访问存储吗?

【问题讨论】:

    标签: javascript reactjs reactjs-flux flux refluxjs


    【解决方案1】:

    我也有类似的问题。我有一个 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
    

    【讨论】:

    • 如果我理解了您的代码,您会触发商店的操作吗?这是好方法还是 hack?
    【解决方案2】:

    常见的方法是从操作执行后端调用,然后在请求成功或失败时分派操作。通过这种方式,您可以使用操作填充您的商店。这意味着存储保持同步,并且可以在更改发生时发出更改。

    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 可以解决数据流问题,因为组件会在需要数据时触发操作。这些操作只是获取数据。

    【讨论】:

    • 这并不能真正回答问题,因为即使数据已经存在于商店中,它也会进行后端调用。
    • 是否需要检查一个用户我是否获取了两次?如果您获取用户,您可以发出更改并将用户数据发送到需要它的组件。数据是否需要经常更新?您不应该让操作直接与商店对话。这种松散耦合是 React 的关键概念之一。通常是组件状态和道具决定它们是否获得了正确的数据,然后触发动作来收集它们。
    • 哦,没看出你不是提问者。您可以忽略我评论中的第一个问题。
    • @magnudae 感谢您的回答,但它没有回答我的问题。我确切地知道通量操作和存储的经典用例是什么,但是如果我已经拥有数据,我该如何防止后端调用。我问action是否可以使用store on not。
    • 我不明白缓存数据是一个糟糕的架构问题? Flux 并不完美,Facebook 的 Relay 正在解决 Flux 的一些问题,并且基本上承认 Flux 将成为未来的前端模式。这是 Flux 中单向流的一个缺点。如果您的商店已经有所需的数据,为什么还要再次向远程服务请求该数据?
    猜你喜欢
    • 1970-01-01
    • 2015-09-13
    • 2021-07-25
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多