I’ve hit an issue while porting my app from Blaze to React.
I have a notifications system that triggers HTML5 notifications and sounds when new documents are added to a collection. A simple example is a chat box that notifies when there is a new item. This was easy enough in Blaze:
Template.chatBox.onCreated(function() {
self.notifications = Chat.find().observeChanges({
added: function(id, doc) {
if (self.ready.get() && doc.user) {
notify(displayname(doc.user), doc.detail, profilePicture(doc.user, 250));
playSound('chat');
}
}
});
});
Template.chatBox.onDestroyed(function() {
this.notifications.stop();
});
But now with React I’m finding it impossible to use this same setup. I realise that to use reactive observers they must be used in getMeteorData()
inside a react component. However due to how getMeteorData()
works by re-running completely whenever there is a change to the reactive data, the notifications observer is recreated and all ‘added’ callbacks for documents that are already there are accordingly recalled. This means whenever a new document is added I’ll get a cacophony of notifications for all of the 20 documents that are already there.
I’ve tried wrapping that data in child component using props and componentWillUpdate
, but since it gives me the whole array of items I can’t effectively see is there is a new item. Additionally, since I’m limiting the publication to 20 documents, componentWillUpdate
runs twice - first with 21 documents and then with 20 as miniMongo is synced with the server.
Any ideas around how to effectively create a simple, reactive collection observer using React?