如何使用Redux在Meteor App中加载数据?

时间:2017-06-27 20:58:35

标签: reactjs meteor redux react-redux

说明:

所以我一直在努力与Redux挣扎。我想我现在明白了这个概念。本质上(并且非常简化):

  1. 商店可保存与您的所有应用相关的状态
  2. 用户与应用程序的互动可以触发具有的操作 描述性标题和一些数据有效载荷
  3. Reducer 使用商店操作有效负载中的当前状态,将更新后的状态置于商店中(在旧状态之上)< / LI>

    现在这很好,因为可以将组件(甚至在反应树的深处)连接到状态,并将状态用作单一事实来源(即始终知道用户是否登录)。

    将Redux与Meteor结合使用时,我的问题就出现了,我仍然不清楚为什么以及想要在Meteor应用程序中放入Redux商店的信息。

    示例

    假设我们有一系列帖子。通常我们只需获取via Minimongo并向用户显示结果。现在假设我们希望将我们的Redux存储作为保存所有数据的单一事实来源。实际上,必须将minimongo与Redux商店同步。 据推测,有人会在componentDidMount上调度一个动作来将数据加载到商店中。

    store.dispatch({
      type: 'GET_POSTS',
      posts: Posts.find().fetch(),
    }); 
    

    然后将其缩减为:

    const postReducer = (state = [], action) => {
      switch (action.type) {
        case 'GET_POSTS':
          return action.posts;
        default:
          return state;
      }
    };
    

    现在为了让这个商店保持最新状态,它必须与Posts集合同步,大概是这样的(虽然我不完全确定我的代码在哪里放置跟踪器):

    Tracker.autorun(() => {
      store.dispatch({
        type: 'GET_POSTS',
        posts: Posts.find().fetch(),
      });
    });
    

    现在我的主要问题是:如何避免Redux商店的大规模膨胀,因为每当有人提交新帖子时,我理解它的方式我们将拥有当前状态+新状态(这基本上是当前状态+新帖子)。 如果你有几个人来回发帖,这可能会很快爆炸,或者即使你的帖子的初始数量很大。

2 个答案:

答案 0 :(得分:3)

感谢您提出这个问题!上周我在训练中学到了React + Redux,我很想将它添加到Meteor中。男孩,从那以后我发现自己身处兔子洞!

我知道你已经熟悉了Redux。对于那些没有的人,你一定要检查these videos

正如我written earlier

  

我已经意识到两个问题。这些问题   当你让所有数据(包括集合)流过时,就会出现   Redux商店:

     
      
  1. 你对Meteor反应性感到失望(使用vanilla Meteor,当MongoDB更新时,View中显示的数据也会更新)。解:   我们可以编写额外的Redux动作&amp;服务器端的Reducer。
  2.   
  3. 你放弃了Meteor乐观的UI(使用vanilla Meteor,当你添加一个新的Widget时,客户端已经尝试预测   甚至在服务器响应之前它应该是什么样子)。在里面   这里的例子,在调用Redux动作时(例如添加一个Widget),我们   本质上等待Meteor方法将Widget插入   在移动到将更新Redux的Reducer之前收集   商店,谁的状态反过来更新我们的视图。 (当然,所有这一切   发生得如此之快,你不会注意到它,但你可能会注意到   如果你是在慢速服务器上运行它或者你有移动设备的话   应用)。解决方案:我们可以在操作中编写其他逻辑   使用新的Widget立即更新Store,如果它转了   我们没有被授权调用Meteor方法,我们仍然可以使用,   在Action中,Promise的.catch来调整Store   (删除我们已经添加的Widget)。
  4.         

    基本上,通过将Redux引入我们的Meteor-React解决方案,   我们错过了Meteor的两大特色。他们俩都可以   使用自编逻辑重建,但坦率地说这似乎是一种耻辱   如此。

我目前看到的方式:

  • 对于不需要管理大量状态的相对简单的应用程序,只是不要将Redux引入React-Meteor堆栈。你会发现自己编写了更多的额外代码(即用于乐观的UI和服务器端的更改)。 Meteor通常首先处理的代码。
  • 对于具有大量状态管理的更复杂的应用程序:Redux似乎只是当前处理React应用程序的最佳方法之一。在这种情况下,将Meteor视为服务器可能是值得的。然后,对MongoDB的调用应始终通过Meteor方法,而Meteor方法又从Redux操作中调用。绝对不应该从Redux Reducer中调用Meteor方法,因为那将是side effect此时你可能想知道仍然使用Meteor的优势是什么 - 这是一个非常好的问题。

除此之外,我一直在考虑一种尝试将两个世界中最好的结合起来的架构。这样的架构仍然会使用Meteor的订阅/发布功能(因此您可以将乐观的UI和服务器端更改保存到客户端),并使用Redux Store进行UI特定的更改(想想过滤器按钮)。

更具体的例子:您可以在应用内通过Meteor发布/订阅获取toDos。但在实际将它们渲染到组件之前,您可以在中间粘贴过滤器功能。此过滤器功能取决于Redux Store对过滤器所说的内容。这又是由您按下的某些按钮定义的,这些按钮通过Redux操作传递到Redux存储。减速。

答案 1 :(得分:3)

将解决方案从问题转移到答案: 还要解决上面的主要问题。人们应该(在大多数情况下)不将来自Mongo的数据放入商店,而是依赖于本地流星功能。有关示例,请参见下文。

  

<强>解决方案:   没有测试,但应该工作。下面显示了一种基于Redux状态从Meteor应用程序中获取Mongo数据的方法。

<强>更新 在此期间测试了类似的东西。切换步骤2和3.这是必要的,因为否则无法访问createContainer中的过滤器。 (因为它从外部组件到内部组件逻辑&#34;在组成组件时有点&#34;

  

<强> 1。设置帖子列表(显示帖子):

class PostsList extends Component {
    render () {
        return (this.props.posts.map((post,i) => {return (<div key={i}>post.header</div>)})
    }
}
     

<强> 2。将组件连接到Meteor:

const PostsListContainer = createContainer((props) => {
    let posts = Meteor.subscribe('getPosts', props.filter);
    return {
        posts
    }
}, PostsList)
     

第3。将组件连接到Redux:

const mapStateToProps = state => {return{filter: state.filter}}

const ConnectedComponent = connect(mapStateToProps,)(PostsListContainer)