【问题标题】:Setting default state for Redux store via axios通过 axios 设置 Redux 存储的默认状态
【发布时间】:2019-07-15 17:58:40
【问题描述】:

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

我知道我应该在 componentDidMount 生命周期挂钩中进行 axios get 调用,但我的 store.js 不是一个类,但我不确定如何。然而,我能够执行 axios.get(URL) 但它以 [[PromiseStatus]]:"resolved", [[PromiseValue]]:{the data i want} 的形式返回一个对象。我读到这些是不可访问的。我想知道是不是因为我没有在生命周期中的正确位置或正确时间进行 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 store。我已经使用邮递员测试了端点,它返回了 JSON 数据。当我在另一个组件中使用 mapStateToProps 读取这个 redux 状态时,我得到一个 Promise 对象。

【问题讨论】:

    标签: node.js reactjs express redux axios


    【解决方案1】:

    我发现你的方法有两个错误。

    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 应该直接去reducer,如下图

    rootReducer (state = defaultState, action) { // ...

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

    这里是simple sample,您可以使用它来更好地理解

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 2021-07-22
      • 2016-05-30
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      相关资源
      最近更新 更多