react-native - Redux Saga 阻塞
问题描述
我是 Redux Saga 和一般生成器的新手,所以我试图围绕如何在调度后执行其余代码之前“等待”调度的操作。
例如:
// Sideeffect to load messages on mount
useEffect(() => {
let mounted = true;
if(mounted) {
dispatch({ type: 'GET_THREAD_MESSAGES', threadId: _id })
setIsLoading(false);
}
return () => {
dispatch({ type: 'CLEAR_FOCUSSED_MESSAGES' })
}
}, [])
当组件第一次挂载时,它将调度GET_THREAD_MESSAGES
. 我rootSaga
通过以下方式观察我的上述动作:
export default function* rootSaga() {
yield all([
...
watchGetThreadMessages(),
watchClearFocussedMessages()
])
}
我适用的传奇:
export function* watchGetThreadMessages() {
yield takeEvery('GET_THREAD_MESSAGES', getThreadMessages)
}
export function* getThreadMessages({ threadId, lastDate }) {
const { token } = yield select(state => state.auth);
try {
const { data } = yield call(getMessages, token, threadId)
yield put({
type: 'GET_THREAD_MESSAGES_SUCCESS',
allMessages: data.messages,
totalMessages: data.count
})
console.log('retrieved messages')
} catch(err) {
console.log(err)
}
}
getMessages
是对我的端点的 axios 调用,从服务器获取数据。问题是,在我完成从 axios 调用中获取消息之前,我setIsLoading
的组件安装后会触发,因为它是异步的。dispatch
通常,如果我在组件内获取数据,我只会等待此响应,但不确定如何等待dispatch
操作。我已经通过将我的 setIsLoading 传递给调度并在 saga 中触发 setIsLoading 来解决它,但这不是最优雅的解决方案,如果有的话,我想知道一个更好的过程。
有什么想法或建议吗?任何人都非常感谢。
解决方案
由于您的操作只是普通的同步函数,因此无法跟踪isLoading
组件内部的状态。您必须改为保留isLoading
在 redux 存储中,并连接到您的组件。每当GET_THREAD_MESSAGES_SUCCESS
调度动作时,reducer 都会将isLoading
value 更改为false
. 例如:
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
// isLoading prop is mapped to state.messages.isLoading
function YourComponent({ isLoading, dispatch }) {
useEffect(() => {
dispatch({ type: 'GET_THREAD_MESSAGES', threadId: 'someId' });
}, []);
if(isLoading) {
return <div>Some loader</div>;
}
return <div>Your component</div>;
}
function mapStateToProps(state) {
return {
isLoading: state.messages.isLoading,
};
}
export default connect(mapStateToProps)(YourComponent);
您的消息缩减器可能如下所示:
export default function messagesReducer(state, action) {
switch (action.type) {
case 'GET_THREAD_MESSAGES':
return {
...state,
isLoading: true,
};
case 'GET_THREAD_MESSAGES_SUCCESS':
return {
...state,
isLoading: false,
allMessages: action.allMessages,
totalMessages: action.totalMessages,
};
default:
return state;
}
}
推荐阅读
- ruby-on-rails - 调用 `format.js` 导致“找不到模板”警告
- javascript - 链二选择 Angular Guard 中的 rxjs 存储
- sql - Django:如何知道原始 sql 和模型查询集所用的时间
- javascript - 在 TypeScript 中从数组中累积映射
- java - 您可以创建一个单独的方法来创建 JFrame 大小吗?
- python - 如何在 QWidget 中居中背景图像
- c# - SonarScanner 未在 SonarQube 中发布结果
- javascript - 如何通过加 2 修复未返回长度字符串值的“截断字符串”
- c# - UWP 键盘加速器 FN 问题
- python - 网络抓取 python/pandas 时忽略丢失的表:mlb 数据