React-Native / Redux-Saga:如何等待分发完成

时间:2019-02-20 09:51:53

标签: react-native react-navigation wait redux-saga dispatch

嗨,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,新的选择器,...

  • 采取行动
  • 更新商店
  • 在componentDidUpdate中监听profileUpdateDone或-FailedStatus
  • 处理错误或执行第二步操作
  • 更新商店
  • 在componentDidUpdate中收听updateProfileImageDone或-FailedStatus
  • 处理错误或导航

商店由于添加了所有废话而变得肮脏不堪。我可以为单个组件引入一个商店,reducer,操作和选择器,但是我有58个组件和7个商店来管理应用程序的全局状态。拥有65个存储,65个reducer,65个选择器文件等似乎难以管理……

我一直在努力寻找一种简洁的设计模式来解决此问题。似乎最基本的基本任务是任何JS框架都应该能够轻松处理,但是由于某种原因,它在redux-saga中不是。

我是唯一面临此问题的人吗,或者redux-saga仅适用于具有以下功能的小型应用程序:不超过20个屏幕?

2 个答案:

答案 0 :(得分:0)

您可以将一个初始状态存储在化简器中,例如isEditObjectDone:false

reduce接收到来自动作的数据时,将其更改为true

然后,在屏幕上componentDidUpdatecomponentWillReceiveProps

执行此操作

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
  }
}