减少 redux-thunk 样板

Posted

技术标签:

【中文标题】减少 redux-thunk 样板【英文标题】:Reducing redux-thunk boilerplate 【发布时间】:2016-09-22 17:19:32 【问题描述】:

在编写redux-thunk 函数时,称为thunks,有很多样板文件可以很容易地抽象掉。例如,在我们的大多数异步 API 调用中,我们都在执行以下操作,而没有任何副作用:

export const LOGIN_REQUEST = 'my-app/auth/LOGIN_REQUEST';
export const LOGIN_RECIEVE = 'my-app/auth/LOGIN_RECIEVE';
export const LOGIN_FAILURE = 'my-app/auth/LOGIN_FAILURE';

// ... reducer code here

export function login(loginHandle, password) 
  return (dispatch, getState, api) => 
    dispatch( type: LOGIN_REQUEST );

    api.post('/auth/login',  loginHandle, password ).then(
      response => dispatch( type: LOGIN_RECIEVE, response ),
      error => dispatch( type: LOGIN_FAILURE, error )
    );
  ;

简单!虽然这涵盖了我们至少 70% 的请求,但我确信有一种优雅的方法可以将上述代码的分配抽象为类似这样的内容(伪代码):

export function login(loginHandle, password) 
  return (dispatch, getState, api) => api('POST', LOGIN_REQUEST, '/auth/login',  loginHandle, password );

当我们需要检查状态和其他副作用时,我们可以返回到适当的 thunk。虽然在大多数情况下......我们可以减少这个?

有什么优雅的想法吗?

【问题讨论】:

【参考方案1】:

Redux Thunk 允许您从 2.1.0 开始注入自定义参数。

const api = createApi() // you would write this function
const store = createStore(
  reducer,
  applyMiddleware(thunk.withExtraArgument(api))
)

// your action creator:
function fetchUser(id) 
  return (dispatch, getState, api) => 
    // you can use api here
  

将来,如果您的 thunk 过于复杂,您可能需要考虑 redux-saga 或 redux-observable。

【讨论】:

正如您在我上面的问题中看到的那样,我们已经将api 作为参数注入。该问题与减少request、receive、fail样板有关 抱歉,我认为“类似这样的东西(伪代码)”意味着您不知道 withExtraArgument(),只是碰巧建议了一个类似的 API。 如果您想减少请求/接收/失败样板,请查看github.com/acdlite/redux-promise。【参考方案2】:

不幸的是,redux 社区没有通用的方法来解决这个确切的问题。我个人觉得人们不应该害怕围绕 redux 编写自己的自定义包装器来处理这种情况。

我创建了一个名为 redux-tiles 的库,它实际上具有您想要的几乎完全相同的 API :) 例如,您的代码将如下所示:

import  createTile  from 'redux-tiles';
const login = createTile(
  type: ['user', 'login'],
  // params is an argument with which you call an action
  fn: ( api, params ) => api('POST', '/auth/login', params),
);

如您所见,这里没有常量,还有一个 reducer。这些东西是自动创建的,因此您不必这样做,也不必对其进行测试。还有其他功能,例如嵌套(例如,相同的功能将应用于按 id 获取项目,但它们将在 reducer 中正确更新)和缓存。您可以查看示例here。

Redux-saga 也是一个好东西,但是如果你需要某种反应性,如果你需要更传统的方法,只是更方便一点的方式来描述你的动作并结合它们,而不是重复自己,然后我发现我的图书馆是完美的匹配。

【讨论】:

以上是关于减少 redux-thunk 样板的主要内容,如果未能解决你的问题,请参考以下文章

使用 redux-thunk 和直接调用 dispatch() 有啥区别

Preact 使用 Storeon 进行状态管路

如何在 Redux/Redux-thunk 中获取 api?

redux-thunk 的唯一好处是啥?

如何使用“redux-thunk”调用 ajax?

redux的中间件之redux-thunk