React-Native / Redux-Saga:如何等待派遣完成

问题描述 投票:3回答:2

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

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

添加所有垃圾,商店变得非常脏。我可以为每个组件引入单个存储,reducer,actions和selectors,但我有58个组件,已经有7个商店来管理应用程序的全局状态。拥有65家商店,65家减少商,65个选择器文件等似乎无法管理......

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

我是唯一一个面临这个问题的人,或者是redux-saga仅适用于小型应用程序,例如不超过20个屏幕?

react-native react-navigation wait redux-saga dispatch
2个回答
0
投票

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

当reducer从动作接收数据时,将其更改为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);
  });

0
投票

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
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.