MeteoRain#02 — 使用Meteor Data传输数据

在上篇文章中,我们基于Meteor1.3和React搭建了一个最简单的应用。我们学习了如何通过NPM包添加React还有如何使用FlowRouter和React Mounter挂载React组件。

这篇文章中,我们继续以MeteoRain为例,讲解如何集成React和Meteor的数据系统。也就是说,我们将讲解如何通过订阅获取数据然后基于数据渲染组件。

React Container模式

在开始之前,我们先来讲一下React Container模式,这种模式能帮助你轻松地分离数据层和表现层。

看一看下面这个截图:

MeteoRain#02 — 使用Meteor Data传输数据_第1张图片
React Container

我们有一个名为BlogPost的组件包含UI,然后我们使用一个叫做「容器组件」的东西来获取数据。接着这个容器会通过props将数据传入UI组件。

Let's Compose Some React Containers

创建Posts集合

我们在lib/collections.js中添加一个名为Posts的集合:

Posts = new Mongo.Collection('posts');

添加虚拟数据

有了Posts这个集合后,我们来添加一些虚拟数据,也称为种子数据。我们在server/configs/initial_adds.js添加如下代码:

if (!Posts.findOne()) {
  for (let lc = 1; lc <= 10; lc++) {
    const title = `This is the post title: ${lc}`;
    const category = lc % 2 ? "public" : "private";
    const content = `Post ${lc}'s content is great!`;
    Posts.insert({title, category, content});
  }
}

发布数据

这里我们从名为Posts的集合中获取MongoDB记录,下面是我们要使用的发布。首先删除autopublish和insecure包:

meteor remove autopublish insecure

然后添加发布:

Meteor.publish('posts.list', function () {
  const selector = {
    category: {$ne: "private"}
  };
  const options = {
    fields: {_id: 1, title: 1},
    sort: {createdAt: -1},
    limit: 10
  };

  return Posts.find(selector, options);
});

注意到,为方便起见,这里所有libserver端代码我们都没有使用ES6的import和export进行模块化的处理,之后随着应用复杂度的增加我们会逐步重构。

UI组件

我们接下来要有一个渲染帖子的组件,代码如下:

import React from 'react';

const PostList = ({posts}) => (
  
This is the post list
    {posts.map(({_id, title}) => (
  • {title}
  • ))}
); export default PostList;

这里我们使用的是一个函数式无状态组件。它会通过props传输数据来渲染UI。

构建容器

现在我们来创建一个容器来获取数据。为此,我们需要使用NPM包react-komposer,它是一个通用的React容器构建库。

import {composeWithTracker} from 'react-komposer';
import PostList from '../components/post_list.jsx';

function composer(props, onData) {
  const handle = Meteor.subscribe('posts.list');
  if(handle.ready()) {
    const posts = Posts.find({}, {sort: {_id: 1}}).fetch();
    onData(null, {posts});
  };
};

export default composeWithTracker(composer)(PostList);

正如你所见,我们的订阅和数据获取逻辑写在composer函数中。这个composer函数在Tracker之中运行。所以你可以在这个函数中编写任何响应式代码。

一旦你获取了数据,你可以像这样调用onData函数:

const posts = Posts.find({}, {sort: {_id: 1}}).fetch();
onData(null, {posts});

composer函数的第一个参数是传递给容器的props。你可以使用容器来加载数据。

然后,我们这样构建容器:

export default composeWithTracker(composer)(PostList);

最后你将得到一个React组件。

渲染容器

现在我们来渲染容器。确保你渲染的是容器,而非UI组件:

import React from 'react';
import {mount} from 'react-mounter';

import Layout from './components/layout.jsx';
import Welcome from './components/welcome.jsx';

import PostList from './containers/post_list';

FlowRouter.route("/", {
  name: "home",
  action() {
    mount(Layout, {
        content: 
    });
  }
});

FlowRouter.route("/posts", {
  name: "postList",
  action() {
    mount(Layout, {
      content: 
    });
  }
});

一旦渲染之后,这是我们在React Dev tools中看到的画面。

MeteoRain#02 — 使用Meteor Data传输数据_第2张图片
PostList Container

正如你看到的那样,我们的UI组件被包裹在容器中。容器通过props传输数据到UI组件中。

最终,我们可以看到,category为private的帖子不会在PostList中显示。

MeteoRain#02 — 使用Meteor Data传输数据_第3张图片
PostList

总结

client目录下,我们主要有两个目录,分别是componentscontainerscomponents目录下存放的是.jsx文件,也就是实际上的React UI组件,而containers目录下存放的是.js文件,是通过composer函数处理导入的UI组件,使之能够方便地处理传入数据的逻辑。而router.jsx由于要挂载组件,用到了这样的语法,所以也是.jsx文件。这里并没有完全地按照Mantra规范来执行,但是随着应用体系的增加,我们会逐步按照Mantra来规范客户端代码,从实际中体会Mantra的好处。

MeteoRain#02 — 使用Meteor Data传输数据_第4张图片
Client File Structure

参考

  1. 原文链接:Using Meteor Data and React with Meteor 1.3 beta
  2. Github Repo: MeteoRain
  3. 流星雨网站:MeteoRain全栈开发 ,网站会在基本UI完成后发布。
MeteoRain#02 — 使用Meteor Data传输数据_第5张图片
Meteor全栈开发

你可能感兴趣的:(MeteoRain#02 — 使用Meteor Data传输数据)