【发布时间】:2021-12-19 02:43:58
【问题描述】:
我目前正在构建一个社交平台,我使用 Mongo Change Streams 来检测任何更改,这些更改将“发出”到单独的套接字,我之前遇到的问题是,一切正常非常好,但现在由于嵌套 cmets 和回复的实现,我的数据库结构发生了变化。因此,我想出了一个解决方法,将三个单独的数组合并为一个数组,其中包含与喜欢和 cmets 关联的嵌套数组信息。所以我想要的是我想从单独的套接字(posts、likes、cmets)中获取数据并合并为一个,因此我已经应用了一个处理程序来检查两者之间的任何变化新旧数据,所以基本上我只是坚持将这三个套接字数据合并到一个数组中,我有点迷失了如何采用这种方法。
更改流
const db = mongoose.connection;
db.once('open', () => {
//post changes
console.log(chalk.blueBright("Setting change streams"));
db.collection('posts').watch()
.on('change', change => {
if(change.operationType === 'insert'){
console.log(chalk.yellowBright('INSERTED'))
io.emit('posts', change.fullDocument);
console.log(change.fullDocument)
}
});
db.collection('posts').watch({ fullDocument: 'updateLookup' })
.on('change', change => {
if(change.operationType === 'update'){
console.log(chalk.yellowBright('UPDATED'));
io.emit('posts', change.fullDocument);
console.log(change.fullDocument)
}
})
//comments changes
db.collection('comments').watch({ fullDocument: 'updateLookup' })
.on('change', change => {
if(change.operationType === 'insert'){
console.log(chalk.yellowBright('INSERTED'))
io.emit('comments', change.fullDocument);
console.log(change.fullDocument)
}
});
db.collection('comments').watch({ fullDocument: 'updateLookup' })
.on('change', change => {
if(change.operationType === 'update'){
console.log(chalk.yellowBright('UPDATED'));
io.emit('comments', change.fullDocument);
console.log(change.fullDocument)
}
})
});
客户端
useEffect 用于检测任何更改帖子
//Check socket changes
useEffect(() => {
//merged posts with comments and likes sockets?
//this is the solution I've come up on merging three arrays but
//I'd like to apply this with the three sockets data that are being retrieved or applied
const newPosts = posts.map(post => ({
...post,
likes: likes.filter(like => post.likes.map(like => like._id).includes(like._id)),
comments: comments.filter(comment => post.comments.map(comment => comment._id).includes(comment._id)),
}))
const handler = (item) => {
setPosts((oldPosts) => {
const findItem = oldPosts.find((post) => post._id === item._id);
if (findItem) {
return oldPosts.map((post) => (post._id === item._id ? item : post));
} else {
return [item, ...oldPosts];
}
});
};
//Sockets
//socket.off("comments", handler);
//socket.off("likes", handler);
return () => socket.off("posts", handler);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
【问题讨论】:
-
这个
useEffect在安装时只运行一次。它永远不会运行,因为您没有传递任何依赖项。如果您希望它在posts更改时运行,您必须在最后定义的空数组中添加posts作为依赖项。将其移动到另一个 useEffect 调用中,否则socket.off也会调用posts中的每个更改 -
这不是原因,因为它在将更改应用于状态时工作得非常好,就像我提到的一切工作正常,但由于我正在使用三个不同的套接字,我想找到一种将套接字输出数据合并到一个数组的方法,因此传递给处理程序的数组将是来自套接字的新合并数组。如果这有意义
标签: reactjs socket.io use-effect changestream