调度到reducer之前如何从动作调用函数?

时间:2020-04-05 23:51:14

标签: javascript reactjs react-redux

我正在使用React Redux应用程序。我有一个动作,在分派动作之前,我要调用一个实用程序函数。

import GetDataFromAPIs from "../utils/menu-creator";
export const UPDATE_DATA = 'UPDATE_DATA';

export const updateData = () => {
    const newData = GetDataFromAPIs();

    return{
        type: UPDATE_DATA, 
        payload: newData
    };
};

而且,这是GetDataFromAPIs.js松散地做的事情:

import React from "react";
import axios from "axios";

const apiOneData = axios.get('/api/a');
const apiTwoData = axios.get('/api/b');


const GetDataFromAPIs = () => {
    axios.all([apiOneData, apiTwoData]).then(axios.spread((...responses) => {
        var firstDataSet = responses[0].data
        var secondDataSet = responses[1].data;
        var dataObject = [];

        dataObject.push(firstDataSet);
        dataObject.push(secondDataSet);

        return dataObject;

    })).catch(errors => {
        console.log("There was an error.");
    })
}

export default GetDataFromAPIs;

但是当应用程序运行时, newData 被设置为未定义。我正在尝试逐步通过GetDataFromAPIs.js,但它会一直跟踪到axios.all,然后脱离该函数。我在控制台中看不到任何错误。

所以我猜想是在解决两个axios.all问题之前​​调度了动作。我认为这将是同步的(newData将获取数据,然后将分派操作)。我做错了吗?

3 个答案:

答案 0 :(得分:2)

您需要将操作明确告知wait才能异步获取该数据。为此,请进行以下更改:


您的GetDataFromAPIs函数应如下所示:

const GetDataFromAPIs = async () => {
    // everything in here stays the same
}

您的updateData函数应如下所示:

export const updateData = async (dispatch) => {
    const newData = await GetDataFromAPIs();

    return dispatch({
        type: UPDATE_DATA, 
        payload: newData
    });
};

请确保dispatch采取行动。

注意:

如果尚未设置redux-thunk,则需要安装该npm模块并更新createStore,使其看起来像这样:

// other imports
import { applyMiddleware, createStore } from 'redux'
import thunk from 'redux-thunk'

const store = createStore(rootReducer, applyMiddleWare(thunk))

答案 1 :(得分:0)

我认为async/await是您所需要的。

export const updateData = async () => {
    const newData = await GetDataFromAPIs();

    return{
        type: UPDATE_DATA, 
        payload: newData
    };
};


const GetDataFromAPIs = async () => {
  try {
    const responses = await axios.all([apiOneData, apiTwoData]).then(axios.spread((...responses);
    var firstDataSet = responses[0].data
    var secondDataSet = responses[1].data;
    var dataObject = [];

    dataObject.push(firstDataSet);
    dataObject.push(secondDataSet);

    return dataObject;

  } catch(errors) {
      console.log("There was an error.");
  })
}

答案 2 :(得分:0)

GetDataFromApis不返回。

你应该做

const GetDataFromApis = async () => {
    return axios.all(...

GetDataFromApis还将返回一个Promise,因此您应该像这样:awaitupdateData中使用它

export const updateData = async () => {
    const newData = await GetDataFromAPIs();

    return {
        type: UPDATE_DATA, 
        payload: newData
    };
};