嗨,Stack Overflow社区!
我正在寻找一种良好的做法和实施方式,以等待组件中的分派操作。
我知道React-Native和Redux-Saga只是说:别等它,让商店更新,通过选择器,您的视图将重新呈现。
一切都很好,但是如何处理这样的事情:
onPress = (object) => {
this.props.editObject(object).then(() => { //editObject is an action
NavigationService.navigateTo(otherScreen);
}).catch((error) => {
// Handle and show validation errors
})
}
当然,在上面的示例中,由于没有then或catch,这是崩溃,因为它是一个动作而不是一个诺言...那么,如何实现这样的流程呢?
我能想到的唯一解决方案是将一个字符串NavigationTo传递给该动作并在saga本身中导航,这根本不是干净的...
有什么建议吗?
编辑:
对于这个问题,我仍然没有找到好的解决方案,而对于redux-saga中间件,我越来越沮丧。
让我们举一个更具体的例子: 我有一个配置文件和图片,需要(依次)更新,在任何普通的js框架中,这都是
try {
setLoading(true);
await updateProfile(...);
await updateProfileImage(...);
navigate(...)
} catch (e) {
//...
} finally {
setLoading(false);
}
要使用redux-saga来实现此目的,需要带一个新商店(带有profileUpdateDone,profileUpdateFailedStatus,profileImageUpdateDone和profileImageUpdateFailedStatus),一个新的reducer,新的选择器,...
商店由于添加了所有废话而变得肮脏不堪。我可以为单个组件引入一个商店,reducer,操作和选择器,但是我有58个组件和7个商店来管理应用程序的全局状态。拥有65个存储,65个reducer,65个选择器文件等似乎难以管理……
我一直在努力寻找一种简洁的设计模式来解决此问题。似乎最基本的基本任务是任何JS框架都应该能够轻松处理,但是由于某种原因,它在redux-saga中不是。
我是唯一面临此问题的人吗,或者redux-saga仅适用于具有以下功能的小型应用程序:不超过20个屏幕?
答案 0 :(得分:0)
您可以将一个初始状态存储在化简器中,例如isEditObjectDone:false
。
reduce接收到来自动作的数据时,将其更改为true
。
然后,在屏幕上componentDidUpdate
或componentWillReceiveProps
执行此操作
if(this.props.isEditObjectDone){
NavigationService.navigateTo(otherScreen);
}
别忘了将状态映射到道具。
编辑:
执行操作以返回 promise
,
像这样
editObject = object => dispatch =>
new Promise((resolve, reject) => {
//your code and dispatch thing
// don't return dispatch instead do this
dispatch({
type: 'something',
...
});
if (something)
resolve(someData);
else
reject(someError);
});
答案 1 :(得分:0)
navigateTo
基本上是一个组成部分,而editObject
是一个状态/传奇事物。 Saga不应该知道屏幕切换。
因此,我们引入一个“胶水”变量,一旦完成编辑,该变量就会更新,并且组件可以收听。
// Saga
function* editObject(payload) {
try {
// do editing
yield put(editDone(...)); // done editing
} catch() {...}
}
// Reducer
let initialState {
editDone: false, // glue variable
};
objList = (state=initialState, action) => {
switch(...) {
case 'EDIT_DONE':
return {...state, editDone: true }; // update glue variable
}
}
// Component
componentDidUpdate(prevProps) {
if (this.props.editDone && !prevProps.editDone) {
// navigate to other screen
}
}