通过axios

时间:2019-07-15 17:58:40

标签: node.js reactjs express redux axios

我有一个节点服务器,它对存储在MongoDB Atlas数据库中的数据执行CRUD操作。我的前端是使用react在我使用redux进行状态管理的情况下制作的。在进行后端设置之前,我通过调用我创建的仅返回JSON数据的函数来初始化redux存储的默认状态。现在,我想通过axios向服务器发出get请求,以检索现在位于Mongo数据库中的相同JSON数据。

我知道我应该在componentDidMount生命周期挂钩中使axios获取调用,但是我的store.js不是类,但我不确定如何。但是,我只能执行axios.get(URL),但它以[[PromiseStatus]]:“ resolved”,[[PromiseValue]]:{我想要的数据}的形式返回一个对象。我读到这些是无法访问的。我想知道是否是因为我没有在生命周期的正确位置或正确时间发出axios呼叫。

import { createStore } from "redux";
//import { syncHistoryWithStore } from "react-router-redux";
//import { browserHistory } from "react-router-dom";
import axios from "axios";

//import the root reducer.
import rootReducer from "../reducers/rootReducer";

//this is just getting JSON from a file
import { getAnnotations } from "../services/fakeEntry";

//create an object for default data
const defaultState = {
  //This is how i was creating the default state before.
  // metadata: getAnnotations()

  //this is what id like to do.But this needs to be in a lifecycle hook?
  metadata: axios
    .get("http://localhost:5100/data/")
    .then(response => {
      return response; 
    })
    .catch(function(error) {
      console.log(error);
    })
};

const store = createStore(rootReducer, defaultState);

export default store;

上面的代码是redux存储。我已经使用邮递员测试了端点,它返回了JSON数据。当我在另一个组件中使用mapStateToProps读取此redux状态时,我得到一个Promise对象。

1 个答案:

答案 0 :(得分:0)

我发现您的做法有两个错误。

  1. Redux基于函数式编程的原理并基于纯函数(没有副作用,如API调用)构建。因此,默认状态应为如下所示的默认空对象

    const defaultState = {
        metadata: {} // It should be empty during store init
        isDataInitialized: false  // You can add additional property to denote, that data is not fetched for the first time
    }
    
  2. axios返回Promise(您已经发现)。因此,从Promise中获取数据,您应该使用.then并在回调中设置数据,或者使用async\await

    以下是使用async\await

    的示例
    // Now it is function, not object
    const getInitalData = () => async dispatch => {
        try {
            let metadata = await axios
                .get("http://localhost:5100/data/");
            // You're dispatching not only the metadata, but also setting isDataInitialized to true, to denote, that data has been loaded
            dispatch ({ type: 'DATA_INITIALIZED', metadata, isDataInitialized: true }); 
        }
        catch {
            console.log(error);
        }
    }
    

    基本上getInitalData是动作创建者,它将调度动作DATA_LOADED进行存储。

并且您应该使用中间件(例如thunk)创建商店,以便能够调度作为功能的动作。

const store = createStore(rootReducer, applyMiddleware(
    thunkMiddleware
))

defaultState应该直接进入减速器,如下所示

rootReducer(状态= defaultState,操作){    // ...

然后,在应用程序的某些根组件中,调用getInitalData从服务器到存储加载数据。

这里是simple sample,您可以用来更好地了解