嗨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,因为它是一个动作而不是一个承诺......那么如何实现这样的流程呢?
我能想出的唯一解决方案是将一个字符串navigateTo传递给动作并在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,actions和selectors,但我有58个组件,已经有7个商店来管理应用程序的全局状态。拥有65家商店,65家减少商,65个选择器文件等似乎无法管理......
我一直在寻找某种干净的设计模式来解决这个问题。它似乎是任何JS框架应该能够轻松处理的最基本的基本任务,但由于某些原因不在redux-saga中。
我是唯一一个面临这个问题的人,或者是redux-saga仅适用于小型应用程序,例如不超过20个屏幕?
您可以在减速器中存储一个初始状态,例如isEditObjectDone:false
。
当reducer从动作接收数据时,将其更改为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);
});
navigateTo
更像是一个组成部分,而editObject
是一个国家/传奇的东西。 Saga不应该知道屏幕转换。
因此,让我们介绍一个“粘合”变量,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
}
}