Meteor React Collection Hooks
How to use Meteor collections pub/sub with react hooks: clean wrapping of meteor subscription data with the useTracker hook.
Let’s start with a simple collection (for example: /imports/api/articles/index.ts
)
import { Mongo } from 'meteor/mongo';
export type Article = {
slug: string,
title: string,
description: string,
text: string,
}
export const ArticlesCollection = new Mongo.Collection<Article>('articles');
// security best practice: deny all client-side updates by default
ArticlesCollection.deny({
insert() { return true; },
update() { return true; },
remove() { return true; },
});
Now define some server-side publications (for example: /imports/api/articles/server/publications.ts
).
import { Meteor } from "meteor/meteor";
import { ArticlesCollection } from "..";
Meteor.publish('articles', () => {
return ArticlesCollection.find({})
});
Meteor.publish('article', ({ slug }) => {
return ArticlesCollection.find({ slug })
});
Remember that you have to include this in the actual server code, like in /server/main.ts
:
import '../imports/api/shared/articles/server/publications';
Now to the interesting part, let’s define two hooks to actually fetch the data
(for example: /imports/api/articles/client/hooks.tsx
)
import { Meteor } from "meteor/meteor";
import { useTracker } from "meteor/react-meteor-data";
import { Article, ArticlesCollection } from "..";
export const useArticle = (slug: string): Article | undefined => {
return useTracker(() => {
const sub = Meteor.subscribe('article', { slug });
if (sub.ready()) {
return ArticlesCollection.findOne({ slug })
} else {
return undefined
}
}, [slug])
}
export const useArticles = (): Article[] => {
return useTracker(() => {
const sub = Meteor.subscribe('articles');
if (sub.ready()) {
return ArticlesCollection.find().fetch()
} else {
return []
}
})
}
Note that the last argument of the useTracker
hook (similar to useEffect
)
does declare a reactive dependency on the slug
in the first hook. It may be
undefined
on the first run (like, when you fetch the slug from react-router with a hook first).
Now rendering some react pages is as easy as this example:
import React from 'react';
import { useParams } from "react-router-dom";
import { useArticle } from '/imports/api/articles/client/hooks';
import { Template } from '/imports/ui/templates/ArticleTemplate';
export default () => {
const { slug } = useParams<{ slug: string }>();
const article = useArticle(slug);
if (article) {
return (<Template article={article} />)
} else {
return (<div>loading data...</div>)
}
};
Linked Technologies
What it's made of
Javascript
Power up your web projects! Essential for dynamic interactions and seamless user experiences. A must-have for every developer's toolkit.
Meteor
Streamline app development with this full-stack platform. Rapid prototyping, real-time updates, and integrated tools make it ideal for startups.
React
React.js: Build dynamic and responsive UIs with ease. Perfect for indie hackers looking to create scalable, efficient web applications!
Typescript
Supercharge your JavaScript with strong typing. Ensure more reliable code and robust applications with this scalable, developer-friendly language.
Linked Categories
Where it's useful
Software Architecture
Dive into the world of Software Architecture where design meets functionality. Explore frameworks, patterns, and best practices that define the structure of software systems, making them robust, scalable, and maintainable.