简体   繁体   English

用于API请求的Redux辅助函数

[英]Redux helper function for api requestes

I'm newbie on react-redux 我是react-redux的新手

I have a project where a lot of api request. 我有一个项目,其中有很多api请求。 I handle this with this pattern: 我用这种模式来处理:

import baseUrl from "store/apiConfig.js";
import axios from "axios";
export const START_FETCH = "START_FETCH";
export const SUCCESS_FETCH = "SUCCESS_FETCH";
export const FAILED_FETCH = "FAILED_FETCH";

export const getData = (id) => {
  return dispatch => {
    dispatch({ type: START_FETCH });
    let data = {
      id: id
    };
    return axios
      .post(baseUrl + "posts", data, {
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json"
        },
      })
      .then(response => {
        dispatch({ type: SUCCESS_FETCH, payload: response.data });
      })
      .catch(error => {
        dispatch({ type: SUCCESS_FAILED, payload: error });
      });
  };
};

Now I want to refactoring my project and make it minimize. 现在,我想重构项目并将其最小化。 So there is have someway make all api requests via one helper function. 因此,总有一些方法可以通过一个辅助函数发出所有api请求。 If yes, how? 如果是,怎么办?

I imagine it will be like that: 我想它将是这样的:

I will dispatch some action from my component and will pass to helper function endpoint and action type like parameter. 我将从组件中分派一些动作,并将其传递给辅助函数的终结点和动作类型,例如参数。

Can someone show me some good practice example about that ? 有人可以告诉我一些良好的做法示例吗?

I use the following function which has helped me immensely in dealing with error handling,method type and also adding custom headers when needed using axios as a wrapper. 我使用以下功能,该功能极大地帮助我处理了错误处理,方法类型,并在需要时使用axios作为包装器添加了自定义标头。

request.js file request.js文件

import axios from 'axios'
import { BASE_API_URL } from '../constants/apiEndpoints' // https://<api_server>.com

const request = function request(options) {
  const onSuccess = function onSuccess(response) {
    return { data: response.data, headers: response.headers }
  }

  const onError = function onError(error) {
    console.error('API REQUEST FAILED:', error.config)

    if (error.response) {
      // Request was made but server responded with something
      // other than 2xx
      console.error('ERROR STATUS:', error.response.status)
      console.error('ERROR DATA', error.response.data)
      console.error('HEADERS', error.response.headers)
    } else {
      // Something else happened while setting up the request
      // triggered the error
      console.error('ERROR MESSAGE :', error.message)
    }

    return Promise.reject(error.response || error.message)
  }
  const [requestConfig, headers] = options
  const apiConfigs = {
    baseURL: BASE_API_URL
  }
  if (headers) {
    apiConfigs.headers = headers
  }
  const client = axios.create(apiConfigs)
  return client(requestConfig)
    .then(onSuccess)
    .catch(onError)
}

export default request

Then I use the function like this 然后我使用这样的功能

const requestOptions = []
requestOptions.push({
        url: `${baseUrl}/posts`
        method: 'PATCH',
        data: <body>
      })
requestOptions.push({ 'Content-Type': 'text/plain' })    // Add this Only if you have headers to add to request
request(requestOptions)

Using this your api call using axios can be reduced to 使用此功能,可以将使用axios的api调用减少为

return request([{url:`${baseUrl}/posts`,method:'POST',data:data},{
      Accept: "application/json",
      "Content-Type": "application/json"
    }]).then((res) => <Your success logic>).catch((err) => <Your error logic>)  // first object in the array to request function is an object with url,method and data key,second object is the headers object.

I am working with the assumption that you want to keep the actions START_FETCH, SUCCESS_FETCH and FAILED_FETCH the same. 我正在假设您要使动作START_FETCH,SUCCESS_FETCH和FAILED_FETCH保持相同。 But you want to be changing the endpoint and the request data. 但是您想更改端点和请求数据。

This is how I would write it: 这就是我的写法:

import baseUrl from "store/apiConfig.js";
import axios from "axios";
export const START_FETCH = "START_FETCH";
export const SUCCESS_FETCH = "SUCCESS_FETCH";
export const FAILED_FETCH = "FAILED_FETCH";

export const getData = (endpoint, data) => {
  return dispatch => {
    dispatch({ type: START_FETCH });
    return axios
      .post(baseUrl + endpoint, data, {
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json"
        },
      })
      .then(response => {
        dispatch({ type: SUCCESS_FETCH, payload: response.data });
      })
      .catch(error => {
        dispatch({ type: SUCCESS_FAILED, payload: error });
      });
  };
};

// example call
getData('differentposts', {id:1,other:'some value'}); // return dispatch

If you want to indicate in the action what you are changing you can change the dispatches payload to for example: 如果要在操作中指示要更改的内容,则可以将调度有效负载更改为例如:

dispatch({ type: SUCCESS_FETCH, payload: {identifier: endpoint, response: response.data} });

That would, of course, require you to edit your reducer to handle the dispatch correctly. 当然,那将需要您编辑减速器以正确处理调度。

Let me know if that answers your question ;) 让我知道这是否回答了您的问题;)

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

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