我正在学习Redux,当用户登录并在注销时断开连接到聊天服务(Chatkit by them )的正确流程时,我会遇到一些麻烦。
到目前为止,我有一个等待LOGIN_REQUEST操作的"auth“传奇,它使用axios登录到REST,然后通过调用USER_SET操作在存储中存储用户名和令牌。
我的问题是,当登录发生并存储凭据时,我是应该设置一个名为CHAT_CONNECT之类的新操作来启动另一个传奇以连接Chatkit,还是应该让聊天传奇监听被解雇的LOGIN_SUCCESS并对其采取行动?这两种方法有什么实际区别吗?
作为一个额外的问题,使用Redux接收和处理来自Chatkit的新websocket消息的最佳方法是什么?下面是从chatkit连接和接收事件的样板代码。
chatManager
.connect()
.then(currentUser => {
currentUser.subscribeToRoom({
roomId: currentUser.rooms[0].id,
hooks: {
onNewMessage: message => {
console.log(`Received new message: ${message.text}`)
}
}
});
})
.catch(error => {
console.error("error:", error);
})发布于 2018-08-12 19:21:33
关于你的第一个问题:
我的问题是,当登录发生并存储凭据时,我是应该设置一个名为CHAT_CONNECT之类的新操作来启动另一个传奇以连接Chatkit,还是应该让聊天传奇监听被解雇的LOGIN_SUCCESS并对其采取行动?
有了这些信息,很难确定哪种方法是理想的,因为这两种方法都将完成相同的功能。我所看到的这两种方法之间最大的区别是依赖的方向。您有两个不同的“模块”(功能、包、...whatever --您称它们为处理单个责任的代码块),让我们称它们为log-in和connect-chat。
如果从CHAT_CONNECT协议内部分派动作log-in,则log-in模块将依赖于connect-chat模块。据推测,connect-chat操作将驻留在connect-chat模块中。
或者,如果您的connect-chat传奇等待LOGIN_SUCCESS,那么您的connect-chat模块将依赖于您的log-in模块。据推测,LOGIN_SUCCESS将驻留在log-in模块中。
这两种方法都没有问题。哪一个最好取决于您的应用程序需求和功能。
如果您可能希望在成功登录后的任何其他时间连接聊天,那么从您的CHAT_CONNECT传奇中分派log-in可能是有意义的。因为聊天不再依赖于登录。有几种情况下,这两种方法都会比另一种方法工作得更好,但这实际上取决于如何设置应用程序的其余部分。
关于奖金问题的:
在redux-saga中连接外部事件的一种方法是通过eventChannels. Docs:https://redux-saga.js.org/docs/api/#eventchannelsubscribe-buffer-matcher完成的。
有一些锅炉板,但我发现这种方法使测试更容易,并真正封装外部功能。下面是一个简单的示例,说明如何将事件通道连接到您提供的代码片段:
export const createOnMessageChannel = () =>
eventChannel((emit) => {
chatManager
.connect()
.then(currentUser => {
currentUser.subscribeToRoom({
roomId: currentUser.rooms[0].id,
hooks: {
onNewMessage: message => emit({ message }),
}
});
})
.catch(error => emit({ error }));
return () => {
// Code to unsubscribe, e.g. chatManager.disconnet() ?
};
});
export function* onMessage({ message, error }) {
if (error) {
yield put(handleError(error));
return;
}
yield put(handleMessage(message));
}
// this is what you pass to your root saga
export function* createOnMessageSaga() {
// using call because this makes it easier to test
const channel = yield call(createOnMessageChannel);
if (!channel) return;
yield takeEvery(channel, onMessage);
}https://stackoverflow.com/questions/51810854
复制相似问题