node.js - 通过 axios 设置 Redux 存储的默认状态

标签 node.js reactjs express redux axios

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

我知道我应该在 componentDidMount 生命周期 Hook 中进行 axios get 调用,但我的 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 存储。我已经使用 postman 测试了端点,它返回 JSON 数据。当我在另一个组件中使用 mapStateToProps 读取此 redux 状态时,我返回了一个 Promise 对象。

最佳答案

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

  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是 Action 创建者,它将分派(dispatch) Action DATA_LOADED来存储。

并且您应该使用中间件(如 thunk)创建存储,以便能够分派(dispatch)作为函数的操作。

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

defaultState 应该直接转到reducer,如下所示

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

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

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

关于node.js - 通过 axios 设置 Redux 存储的默认状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57044956/

相关文章:

html - React Material UI-制作一个按钮打开文件选择器窗口

javascript - React onchange 事件 : this. setState() 未设置状态?

node.js - Node - express-http-proxy - 在代理之前设置 header

node.js - Elasticsearch 删除操作

javascript - 棱镜2 : how to fetch nested fields?

reactjs - React 模式对话框的内容不可用于使用 mount() 的 enzyme 测试

mysql - 序列化 findAll,其中列值与表中至少一项其他项目相同

node.js - NodeJS - 需要错误密码

node.js - 在 Node.js 中使用 async/await 正确处理错误

node.js - Azure:尝试获取 blob 内容时函数停止工作