React Redux - 在 Reducer 中添加异步方法是一种反模式吗?

IT技术 reactjs react-native redux
2021-04-11 01:38:49

我对整个 react-native/redux 世界还很陌生,所以也许这个问题听起来很愚蠢:)

我知道对于 API 调用或类似的东西,约定是使用中间件,但它总是必要的吗?(它添加了很多样板文件)。

我成功地在减速器中添加了一个异步方法来管理设备 API 连接,例如应用内或本地通知,但我想知道以这种方式处理它是否可以。

例如,在我的减速器中有这个方法:

function initInApp(state, itemSkus){
  init(state, itemSkus);
  return {
    ...state,
    itemSkus: itemSkus,
  }
}

而这个,管理异步部分:

async function init(state, itemSkus){
  try {
    if( !state.isInit ){
      const prepare = await Promise.all(RNIap.prepareAndroid());
      return{
        ...state,
        isInit: true,
        errorCode: false,
      }
    }
    else {
       return ...state;
    }
  } catch (errorCode) {
    return{
      ...state,
      isInit: false,
      errorCode: errorCode,
      itemSkus: itemSkus
    }
  }
}

也许它在性能方面效率不高或难以维护..您对此有何看法?

谢谢 :)

3个回答

是的。减速器不应该有任何副作用。Reducers 需要是 Pure Functions 才能让 redux 高效工作。这里有几个链接试图解释为什么 redux 需要 reducers 是纯函数,以及为什么纯 reducers 在 redux 中如此重要

正如其他人指出的那样,thunk 中间件是在react中处理异步的常用方法。

另一种不需要任何库的方法是通过称为“Fat Action Creators”的模式。动作创建者可以处理异步操作。他们这样做的方法是返回一个围绕函数的“调度”包装器,因此它可以自己调度动作。

以下是摘自 Medium 文章的示例:
我将业务逻辑放在 React-Redux 应用程序中的何处
(本文也链接到redux 常见问题解答):

const fetchUser = (dispatch, id) => {
  dispatch({ type: USER_FETCH, payload: id });
  axios.get(`https://server/user/${id}`)
   .then(resp => resp.data)
   .then(user => dispatch({ type: USER_FETCH_SUCCESS, 
                            payload: user }))
   .catch(err => {
     console.error(err); // log since might be a render err
     dispatch({ type: USER_FETCH_FAILED, 
                            payload: err, 
                            error: true });
   });
};

redux-thunk 以外的软件包包括:

  • https://www.npmjs.com/package/redux-logic

    “所有业务逻辑和操作副作用的一个地方”“使用 redux-logic,您可以自由地以自己喜欢的 JS 风格编写逻辑:`

    • 普通回调代码 - dispatch(resultAction)
    • Promise - 返回 axios.get(url).then(...)
    • 异步/等待 - 结果 = 等待获取(url)
    • observables - ob$.next(action1)`
  • redux-saga

    redux-saga 是一个库,旨在使应用程序的副作用(即异步事物,如数据获取和不纯的事物,如访问浏览器缓存)更易于管理、更有效地执行、更易于测试和更好地处理故障。uses generators so make sure you're confortable using them.

  • redux-observable,如果你更喜欢 RxJS Observables
    这个库是由 Jay Phelps 创建的,这篇中等文章“redux-observable”是由 Ben Lesh 写的。两者在 React 社区中都很有名。

  • redux-thunk为了完整性。

  • 前面提到的文章中列出了其他包:
    我将业务逻辑放在 React-Redux 应用程序中的何处

一切顺利 !

在我从事的一个项目中,我们将异步代码放在操作中,并使用称为“thunk”的“中间件”来解析对我们的减速器可以使用的对象的Promise。所有减速器被写成其采取同步方法stateaction并返回一个新的state

react中的减速器的唯一目的是传递更新的状态。是的,任何 Api 调用或其他“动作”都不能在减速器中执行,这是一种反模式。您可以使用诸如 react-thunk 之类的各种异步操作module来执行异步操作