Meteor.js 3 + React
在本教程中,我们将使用 React 和 Meteor 3.0 创建一个简单的待办事项应用程序。Meteor 与其他框架(如 Blaze、Vue 3、Solid 和 Svelte)配合使用效果很好。
React 是一个流行的用于构建用户界面的 JavaScript 库。它允许您通过组合 UI 组件来创建动态和交互式应用程序。React 使用声明式方法,您根据状态定义 UI 的外观,并且在状态发生变化时有效地更新视图。借助 JSX(一种将 JavaScript 和 HTML 结合在一起的语法扩展),React 使创建可重用组件变得容易,这些组件可以管理自己的状态并在浏览器中无缝渲染。
要开始构建您的 React 应用程序,您需要一个代码编辑器。如果您不确定选择哪个,Visual Studio Code 是一个不错的选择。安装后,您可以通过添加 Meteor Toolbox 等扩展来增强您的体验。
让我们开始构建您的应用程序!
目录
1:创建应用程序
1.1:安装 Meteor
首先,我们需要安装 Meteor。
如果您尚未安装 Meteor,可以通过运行以下命令进行安装
npx meteor
1.2:创建 Meteor 项目
使用 meteor create
命令并带有 --react
选项和您的项目名称(您也可以省略 --react
选项,因为它是默认选项)是最简单的设置 Meteor 和 React 的方法。
meteor create simple-todos-react
Meteor 将为您创建所有必要的文件。
位于 client
目录中的文件正在设置您的客户端(Web),例如,您可以看到 client/main.jsx
,其中 Meteor 将您的 App 主组件渲染到 HTML 中。
此外,检查 server
目录,其中 Meteor 正在设置服务器端(Node.js),您可以看到 server/main.js
正在使用一些数据初始化您的 MongoDB 数据库。您无需安装 MongoDB,因为 Meteor 提供了一个嵌入式版本,供您随时使用。
您现在可以使用以下命令运行您的 Meteor 应用程序
meteor run
不用担心,从现在开始,Meteor 将使您的应用程序与您所有的更改保持同步。
您的 React 代码将位于 imports/ui
目录中,App.jsx
文件是您的 React 待办事项应用程序的根组件。
快速浏览一下 Meteor 创建的所有文件,您现在不必理解它们,但了解它们在哪里是有益的。
1.3:创建任务组件
您现在将进行第一次更改。在您的 ui
文件夹中创建一个名为 Task.jsx
的新文件。
此文件将导出一个名为 Task
的 React 组件,该组件将表示待办事项列表中的一个任务。
import React from "react";
export const Task = ({ task }) => {
return <li>{task.text}</li>;
};
由于此组件将在列表中,因此您将返回一个 li
元素。
1.4:创建示例任务
由于您尚未连接到服务器和数据库,因此让我们定义一些示例数据,这些数据将很快用于渲染任务列表。它将是一个数组,您可以将其称为 tasks
。
import React from 'react';
const tasks = [
{_id: 1, text: 'First Task'},
{_id: 2, text: 'Second Task'},
{_id: 3, text: 'Third Task'},
];
export const App = () => ...
您可以在每个任务上将任何内容作为您的 text
属性。发挥创意!
1.5:渲染示例任务
现在,我们可以使用 React 实现一些简单的渲染逻辑。我们现在可以使用我们之前的 Task
组件来渲染我们的列表项。
在 React 中,您可以使用 {
}
在它们之间编写 Javascript 代码。
请参见下面,您将使用 Array
对象的 .map
函数来迭代您的示例任务。
import React from 'react';
import { Task } from './Task';
const tasks = ..;
export const App = () => (
<div>
<h1>Welcome to Meteor!</h1>
<ul>
{ tasks.map(task => <Task key={ task._id } task={ task }/>) }
</ul>
</div>
);
请务必将 key
属性添加到您的任务中,否则 React 将发出警告,因为它会将许多相同类型的组件视为同级。如果没有密钥,如果需要,React 将难以重新渲染其中一个。
您可以 此处阅读更多关于 React 和 Keys 的信息。
从您的 App
组件中删除 Hello
和 Info
,请记住还要删除文件顶部对它们的导入。也删除 Hello.jsx
和 Info.jsx
文件。
1.6:热模块替换
Meteor 在使用 React 时默认情况下已经为您添加了一个名为 hot-module-replacement
的包。此包更新在重建期间修改的正在运行的应用程序中的 JavaScript 模块。减少开发过程中的反馈周期,以便您可以更快地查看和测试更改(它甚至在构建完成之前更新应用程序)。您也不会丢失状态,您的应用程序代码将更新,并且您的状态将保持不变。
在下一步中,我们将使用我们的 MongoDB 数据库来存储我们的任务。
2:集合
Meteor 已经为您设置了 MongoDB。为了使用我们的数据库,我们需要创建一个集合,我们将在此处存储我们的文档,在本例中为我们的 tasks
。
您可以 此处阅读更多关于集合的信息。
在此步骤中,我们将实现所有必要的代码,以便使用 React hook 运行我们的任务的基本集合。
2.1:创建任务集合
我们可以通过在 imports/api/TasksCollection.js
中创建一个新文件来创建一个新的集合来存储我们的任务,该文件实例化一个新的 Mongo 集合并将其导出。
import { Mongo } from "meteor/mongo";
export const TasksCollection = new Mongo.Collection("tasks");
请注意,我们将文件存储在 imports/api
目录中,这是一个用于存储与 API 相关的代码(如发布和方法)的地方。您可以根据需要命名此文件夹,这只是一种选择。
您可以删除此文件夹中的 links.js
文件,因为我们不会使用此集合。
您可以 此处阅读更多关于应用程序结构和导入/导出的信息。
2.2: 初始化任务集合
为了使我们的集合正常工作,你需要在服务器端导入它,以便它设置一些管道。
你可以使用 `import "/imports/api/TasksCollection"` 或 `import { TasksCollection } from "/imports/api/TasksCollection"`(如果你要在同一个文件中使用),但请确保已导入。
现在很容易检查我们的集合中是否有数据,如果没有,我们也可以轻松插入一些示例数据。
你不需要保留 `server/main.js` 的旧内容。
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "/imports/api/TasksCollection";
const insertTask = (taskText) =>
TasksCollection.insertAsync({ text: taskText });
Meteor.startup(async () => {
if ((await TasksCollection.find().countAsync()) === 0) {
[
"First Task",
"Second Task",
"Third Task",
"Fourth Task",
"Fifth Task",
"Sixth Task",
"Seventh Task",
].forEach(insertTask);
}
});
因此,你正在导入 `TasksCollection` 并向其中添加一些任务,通过迭代一个字符串数组,并对每个字符串调用一个函数,将该字符串作为我们的 `text` 字段插入到我们的 `task` 文档中。
2.3: 渲染任务集合
现在进入有趣的部分,你将使用一个 React 函数组件和一个名为 `useTracker` 的 Hook(来自名为 react-meteor-data 的包)来渲染任务。
Meteor 同时支持 Meteor 包和 NPM 包,通常,Meteor 包使用 Meteor 内部功能或其他 Meteor 包。
此包已包含在 React 骨架中(`meteor create yourproject`),因此你无需添加它,但你始终可以通过运行 `meteor add package-name` 来添加 Meteor 包。
meteor add react-meteor-data
现在,你已准备好导入此包中的代码,从 Meteor 包导入代码时,与 NPM 模块唯一的区别在于,你需要在导入语句的 from 部分前面加上 `meteor/`。
由 `react-meteor-data` 导出的 `useTracker` 函数是一个 React Hook,它允许你在 React 组件中实现响应式。每次数据通过响应式发生变化时,你的组件都会重新渲染。很酷,对吧?
有关 React Hook 的更多信息,请阅读 此处。
import React from "react";
import { useTracker } from "meteor/react-meteor-data";
import { TasksCollection } from "/imports/api/TasksCollection";
import { Task } from "./Task";
export const App = () => {
const tasks = useTracker(() => TasksCollection.find({}).fetch());
return (
<div>
<h1>Welcome to Meteor!</h1>
<ul>
{tasks.map((task) => (
<Task key={task._id} task={task} />
))}
</ul>
</div>
);
};
但是等等!缺少一些东西。如果你现在运行你的应用,你会发现没有渲染任何任务。
这是因为我们需要将我们的数据发布到客户端。
首先,为我们的任务创建一个发布。
imports/api/TasksPublications.js
import { Meteor } from "meteor/meteor";
import { TasksCollection } from "./TasksCollection";
Meteor.publish("tasks", () => {
return TasksCollection.find();
});
现在,我们需要在我们的服务器中导入此文件。
...
import { TasksCollection } from '/imports/api/TasksCollection';
import "../imports/api/TasksPublications";
const insertTask = taskText => TasksCollection.insertAsync({ text: taskText });
...
剩下的唯一事情是订阅此发布。
imports/ui/App.jsx
import React from 'react';
import { useTracker, useSubscribe } from 'meteor/react-meteor-data';
import { TasksCollection } from '/imports/api/TasksCollection';
import { Task } from './Task';
export const App = () => {
const isLoading = useSubscribe("tasks");
const tasks = useTracker(() => TasksCollection.find({}).fetch());
if (isLoading()) {
return <div>Loading...</div>;
}
...
}
如你所见,当使用 `useSubscribe` 订阅发布时,你会得到一个 `isLoading` 函数,你可以在数据准备好之前使用它来渲染一些加载组件。
有关发布/订阅的更多信息,请查看我们的 文档。
查看你的应用现在应该是什么样子。

你可以在服务器上的 MongoDB 中更改你的数据,你的应用会做出反应并为你重新渲染。
你可以通过在应用文件夹的终端中运行 `meteor mongo` 或使用 Mongo UI 客户端(例如 NoSQLBooster)连接到你的 MongoDB。你的嵌入式 MongoDB 正在端口 `3001` 上运行。
查看如何连接。

查看你的数据库。

你可以双击你的集合以查看存储在其中的文档。

在下一步中,我们将使用表单创建任务。
3: 表单和事件
所有应用都需要允许用户对存储的数据执行某种类型的交互。在我们的例子中,第一种交互类型是插入新的任务。没有它,我们的待办事项应用将毫无用处。
用户在网站上插入或编辑数据的主要方法之一是通过表单。在大多数情况下,使用 `