关于你的第一个问题:
我的问题是,当登录发生并存储凭据时,我应该放置一个名为 CHAT_CONNECT 的新操作,它会启动另一个传奇以连接到 Chatkit,还是应该让聊天传奇收听被触发的 LOGIN_SUCCESS 和采取行动?
根据所提供的信息,很难确定哪种方法是理想的,因为任何一种方法都将完成相同的功能。我看到的两种提议方法之间的最大区别是依赖的方向。您有两个不同的“模块”(功能、包、......无论您如何称呼处理单一职责的代码块),让我们调用它们log-in并connect-chat.
如果您CHAT_CONNECT从log-insaga 中分派一个动作,您的log-in模块将依赖于该connect-chat模块。据推测,该connect-chat动作将存在于connect-chat模块中。
或者,如果您的 connect-chatsaga 等待LOGIN_SUCCESS,那么您的connect-chat模块将依赖于您的log-in模块。据推测,LOGIN_SUCCESS将住在log-in模块中。
这两种方法都没有错。哪个最好取决于您的应用程序需求和功能。
如果您可能想在成功登录后的任何其他时间连接聊天,那么CHAT_CONNECT从您的log-insaga 中调度可能是有意义的。因为聊天不再依赖于登录。在某些情况下,任何一种方法都会比另一种更好,但这实际上取决于您的应用程序的其余部分是如何设置的。
关于您的奖金问题:
在 redux-saga 中挂钩外部事件的一种方法是通过eventChannels. 文档: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);
}