Step4: コレクションを作成しよう!(Memos Collection)
このステップではMeteorのコレクションをReactと一緒に使用する方法を学びます。
Memos Collection
Meteorにはコレクション(Collection)という機能があります。
コレクションはデータベース(MongoDB)の操作APIを提供するもので、Meteorに標準で備わっている機能です。minimongo
という仕組みにより、サーバーとクライントで同じAPIでMongoDB操作ができるようになっています。
このコレクション機能を使って、メモ用のデータを保存するコレクション(Memos Collection)を作成していきましょう。
imports/api/memos
ディレクトリを作成し、その中に memos.js
ファイルを作成します。
$ mkdir -p imports/api/memos
$ touch imports/api/memos/memos.js
imports/api/memos/memos.js
import { Mongo } from 'meteor/mongo';
export const Memos = new Mongo.Collection('Memos');
// for debug
if (Meteor.isDevelopment) {
global.collections = global.collections || {};
global.collections.Memos = Memos;
}
続いて、Memosコレクションの初期データを用意しましょう。
Memosコレクションが空だった場合に初期データを投入するコードを server/main.js
に追加します。
server/main.js
import { Meteor } from 'meteor/meteor';
import { Memos } from '../imports/api/memos/memos';
Meteor.startup(() => {
if (Memos.find().count() === 0) {
const data = [
{content: 'Memo 1'},
{content: 'Memo 2'},
{content: 'Memo 3'},
{content: 'Memo 4'},
{content: 'Memo 5'},
];
data.forEach(memo => Memos.insert(memo));
}
});
初期データを追加するため一度 meteor
コマンドを Ctrl+C
で終了させます。
# Ctrl+C
その後、再度 meteor
コマンドを実行します。
meteor
初期データが追加されたかどうか確認するため、別のターミナルウィンドウを開き、Meteorアプリのディレクトリ内で以下のコマンドを実行します。
$ meteor mongo
MongoDB shell version: 2.6.7
connecting to: 127.0.0.1:3001/meteor
meteor:PRIMARY>
すると、MongoDBのシェル(REPL)が起動します。
Memosコレクションのデータを確認してみましょう。
meteor:PRIMARY> show collections;
Memos
system.indexes
meteor:PRIMARY> db.Memos.find();
{ "_id" : "KnpEcfkn9d9RsEiML", "content" : "Memo 1" }
{ "_id" : "9sBNyne4pYjwkvWXp", "content" : "Memo 2" }
{ "_id" : "Aop64vXHtXE2mFgf9", "content" : "Memo 3" }
{ "_id" : "H87FDebk9ominCPx8", "content" : "Memo 4" }
{ "_id" : "j3sN7YosasFBs8iCM", "content" : "Memo 5" }
meteor:PRIMARY> exit
bye
Memosコレクションにデータが追加されていますね!
それでは、Memosコレクションのデータをクライアント側で表示させましょう。
createContainer() - ReactMeteorData
Meteorのコレクションは「リアクティブデータソース」と呼ばれ、データが更新されると、その変更を通知する仕組みがあります。クライアント側でコレクションの変更を検知し、自動的にUIを書き換える仕組みを提供するのがreact-meteor-data
Meteorパッケージです。
Meteor 1.2では react-meteor-data
パッケージの ReactMeteorData
mixin を使用することで、変更検知と画面の書き換えを自動で行っていました。
Meteor 1.3ではReactのmixinではなく、react-meteor-data
が提供する createContainer()
を使い、Meteorのリアクティブデータソースを管理する「コンテナ」を作ってコンポーネントをラップすることで、画面の自動更新を実現しています。
AppContainer
それでは早速ReactMeteorDataコンテナを作っていきます。
AppLayoutにMemosコレクションのデータを渡すための、AppContainerを作成します。
$ mkdir -p imports/ui/containers
$ touch imports/ui/containers/AppContainer.js
imports/ui/containers/AppContainer.js
import AppLayout from '../layouts/AppLayout';
import { Memos } from '../../api/memos/memos';
import { createContainer } from 'meteor/react-meteor-data';
export default createContainer(() => {
return {
memos: Memos.find().fetch(),
};
}, AppLayout);
そしてAppLayoutを呼び出していた client/main.js
を書き換えます。
client/main.js
import { Meteor } from 'meteor/meteor';
import React from 'react';
import { render } from 'react-dom';
import AppContainer from '../imports/ui/containers/AppContainer';
Meteor.startup(() => {
render(
<AppContainer />,
document.getElementById('render-root')
);
});
コードを書き換えると次のような表示になります。
なお、AppContainr を追加したことにより各コンポーネントの親子関係は次のようになります。
<AppContainer>
<AppLayout>
<Header />
<MemoList>
<MemoItem />
<MemoItem />
<MemoItem />
...
</MemoList>
</AppLayout>
</AppContainer>
Meteor ではコレクション等のリアクティブデータソースに関して、createContainer()
で作成したコンテナでデータを管理し、各コンポーネントが必要なデータは親コンポーネントから子コンポーネントにデータを渡すようにすると、保守性・再利用性の高いコンポーネントになります。
複数クライアント間でのデータ同期
Meteorには標準でデータの同期機構が備わっています。また、データベース(MongoDB)のドキュメントが変更されると、それに対応するMeteorコレクションも自動的に変更される仕組みになっています。動きを確かめてみましょう。
すでに開いているWebブラウザとは別のWebブラウザウィンドウを開き、2画面で http://localhost:3000/ を表示させます。
その状態で、片方のWebブラウザのWebインスペクタを起動し、Consoleで以下のコマンドを入力します。
// Webインスペクタで実行
collections.Memos.insert({content: 'New Memo Data'})
上記コマンドを実行すると、メモリストにNew Memo Dataというデータが表示されます。また、もう一方のWebブラウザにもほぼ同時に同じデータが反映されます。
このように、Meteorではコレクションを使うことで、複数クライアント間でのデータ同期を簡単に実現できます。
次のステップへ進みましょう。