简体   繁体   English

减少redux-thunk样板

[英]Reducing redux-thunk boilerplate

When writing redux-thunk functions, known as thunks there is allot of boilerplate that could be easily abstracted away. 在编写redux-thunk函数时,称为thunk ,可以很容易地抽象出很多样板文件。 For example in most of our async API calls we are doing the following, without any side-effects: 例如,在我们的大多数异步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 })
    );
  };
}

Easy! 简单! Although as this covers at least 70% of our requests I'm sure there is an elegant way to abstract away allot of the above code to something like this (pseudo code): 虽然因为这涵盖了我们至少70%的请求,但我确信有一种优雅的方法可以将上述代码抽象为类似的东西(伪代码):

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

When we need to check the state and other side effects we can go back to a proper thunk. 当我们需要检查状态和其他副作用时,我们可以回到适当的thunk。 Although for most cases... we could cut this down? 虽然在大多数情况下...我们可以减少这个?

Any elegant ideas? 任何优雅的想法?

Redux Thunk lets you inject a custom argument since 2.1.0. 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
  }
}

In the future, if your thunks get too complicated, you might want to consider redux-saga or redux-observable . 在将来,如果你的thunk太复杂了,你可能想要考虑redux-sagaredux-observable

Unfortunately, there is no common way in redux community to approach this exact problem. 不幸的是,在redux社区中没有通用的方法来解决这个问题。 I personally feel that people should not be afraid to write their own custom wrappers around redux to deal with exactly such situations. 我个人觉得人们不应该害怕在redux周围编写自己的自定义包装器来处理这种情况。

I created a library called redux-tiles , which actually has almost exact API as you want :) For instance, you code will look like the following: 我创建了一个名为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),
});

As you can see, there are no constants here, as well as a reducer. 如您所见,此处没有常量,还有减速器。 These things are created automatically, so you don't have to do it, as well as testing it. 这些东西是自动创建的,因此您不必执行此操作,也不必对其进行测试。 There are other features, like nesting (so same function will be applied for fetching items by id, for instance, but they will be correctly updated inside reducer) and caching. 还有其他功能,例如嵌套(因此,相同的功能将应用于通过id获取项目,但它们将在reducer内正确更新)和缓存。 You can checkout examples here . 您可以在这里查看示例。

Redux-saga is a good thing too, but it is more if you need some sort of reactivity, if you need more traditional approach, just a little bit more convenient way to describe your actions and combine them, without repeating yourself, then I find my library to be a perfect match. Redux-saga也是一件好事,但是如果你需要某种反应,如果你需要更传统的方法,只需要更方便的方式描述你的行为并将它们结合起来,而不重复自己,那就更好了,然后我发现我的图书馆是一个完美的匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM