Redux:可重用的操作 [英] Redux: Reusable actions

查看:59
本文介绍了Redux:可重用的操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动作,它使用了 redux thunk,看起来像这样:

I have an action, that uses a redux thunk, that looks like so:

export function fetchData(query) {
  return dispatch => {
    return fetch(`http://myapi?query=${query}` ,{mode: 'cors'})
      .then(response => response.json())
      .then(json => { dispatch(someOtherAction(json)) })
    }
  }
}

然后我的 someOtherAction 实际上更新状态:

and then my someOtherAction actually updates state:

export function someOtherAction(data) {
    return {
        action: types.SOME_ACTION,
        data
    }
}

但我希望 fetchData 动作创建者可以重复使用,以便我的应用程序的不同部分可以从 myapi 获取数据,然后有不同的部分国家以此为基础.

But i want it to be possible for the fetchData action creator to be reusable so that different parts of my app can fetch data from myapi and then have different parts of the state based on that.

我想知道重用此操作的最佳方法是什么?将第二个参数传递给我的 fetchData 动作创建者是否可以接受,该动作规定在成功获取时调用哪个动作:

I'm wondering what is the best way to reuse this action? Is it acceptable to pass a second parameter in to my fetchData action creator that stipulates which action is called on a successful fetch:

export function fetchData(query, nextAction) {
  return dispatch => {
    return fetch(`http://myapi?query=${query}` ,{mode: 'cors'})
      .then(response => response.json())
      .then(json => { dispatch(nextAction(json)) })
    }
  }
}

或者是否有一种可接受的方式来做这种事情?

Or is there an accepted way of doing this sort of thing?

推荐答案

我为此使用了中间件.我已经在那里定义了 fetch 调用,然后在我的操作中,我发送 URL 来 fetch 和完成后要调度的操作.这将是一个典型的获取操作:

I use a middleware for that. I have defined the fetch call in there, then in my actions I send the URL to fetch and the actions to dispatch when completed. This would be a typical fetch action:

const POSTS_LOAD = 'myapp/POST_L';
const POST_SUCCESS = 'myapp/POST_S';
const POST_FAIL = 'myapp/POST_F';

export function fetchLatestPosts(page) {
  return {
    actions: [POSTS_LOAD, POST_SUCCESS, POST_FAIL],
    promise: {
      url: '/some/path/to/posts',
      params: { ... },
      headers: { ... },
    },
  };
}

调用该操作时,POST_LOAD 操作将在执行获取请求之前由中间件自动分派.如果一切顺利,POST_SUCCESS 动作将与 json 响应一起发送,如果出现问题,POST_FAIL 动作将由中间件发送.

When calling that action, the POST_LOAD action will be dispatch automatically by the middleware just before the fetch request it's executed. If everything goes well the POST_SUCCESS action will be dispatched with the json response, if something goes wrong the POST_FAIL action will be dispatched by the middleware.

所有的魔法都在中间件中!它与此类似:

All the magic it's in the middleware! And it's something similar to this:

export default function fetchMiddleware() {
  return ({ dispatch, getState }) => {
    return next => action => {
      if (typeof action === 'function') {
        return action(dispatch, getState);
      }

      const { promise, actions, ...rest } = action;

      if (!promise) {
        return next(action);
      }

      const [REQUEST, SUCCESS, FAILURE] = actions;
      next({ ...rest, type: REQUEST }); // <-- dispatch the LOAD action


      const actionPromise = fetch(promise.url, promise); // <-- Make sure to add the domain

      actionPromise
        .then(response => response.json())
        .then(json => next({ ...rest, json, type: SUCCESS })) // <-- Dispatch the success action
        .catch(error => next({ ...rest, error, type: FAILURE })); // <-- Dispatch the failure action

      return actionPromise;
    };
  };
}

通过这种方式,我可以将所有请求放在一个地方,并且可以定义在请求完成后要运行的操作.

This way I have all my requests on a single place and I can define the actions to run after the request it's completed.

------------EDIT----------------

为了获取reducer上的数据,你需要使用你在原action creator上定义的action名.以下示例显示了如何处理来自中间件的 POST_SUCCESS 操作以从 json 响应中获取 posts 数据.

In order to get the data on the reducer, you need to use the action name you defined on the original action creator. The following example shows how to handle the POST_SUCCESS action from the middleware to get the posts data from the json response.

export function reducer(state = {}, action) {
  switch(action.type) {
    case POST_SUCCESS:  // <-- Action name
      return {
        ...state,
        posts: action.json.posts, // <-- Getting the data from the action
      }
    default:
      return state;
  }
}

我希望这会有所帮助!

这篇关于Redux:可重用的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆