反应–异步/等待似乎没有在等待

时间:2019-01-17 06:35:06

标签: reactjs react-async

我以前曾在“无法读取未定义的属性'数据'”错误消息下发布此问题。但是在研究了几个小时后,我发现我的问题确实归结为我的“异步/等待”似乎并非如此。 。 。 。等待中!是的,我确实检查了此问题的其他几个版本。 :)

我正在构建一个React表单,该表单将有几个下拉框,其中填充了来自MongoDB的数据。我是React的新手,还是MongoDB的初学者。

通过将所有代码都挤入一个文件中,我已经能够成功地将数据放入下拉列表中。现在,我正尝试通过将片段适当地分成单独的文件来开始重构代码。这就是我遇到“数据延迟”问题的地方。

当“ componentDidMount”调用“ fetchProjects”功能时,该功能将使用“项目服务”文件中的“ getProjects”功能从MongoDB获取项目列表。当“ fetchProjects”中的console.log运行时,它以未定义状态返回。但是,然后在数据集恢复为未定义状态(并导致过程出错)之后,我的确从“ getProjects”功能获取了项目对象数组的控制台日志。

我已经能够使此过程与“ getProjects”函数中的硬编码对象数组数据一起使用,因此告诉我,问题出在从MongoDB实际获取数据所需的时间上。

请告诉我,有一种无需使用Redux即可解决此问题的方法! :D

这是我的App.js文件–

import React, { Component } from "react";
import "./App.css";
import { getProjects } from "./services/svcProjects";

class App extends Component {
  state = {
    data: {
      selProject: ""
    },
    projects: []
  };

  async componentDidMount() {
    await this.fetchProjects();
  }

  async fetchProjects() {
    const { data: projects } = await getProjects();
    console.log(projects);
    this.setState({ projects });
  }

  render() {
    return (
      <div className="App">
        <h1>Project Log</h1>
        <label htmlFor={"selProject"}>{"Project"}</label>
        <select name={"selProject"} id={"selProject"} className="form-control">
          <option value="" />
          {this.state.projects.map(a => (
            <option key={a._id} value={a.project}>
              {a.project}
            </option>
          ))}
        </select>
      </div>
    );
  }
}

export default App;

这是“项目服务”文件。同样,请注意,此处的console.log语句表明我仍在从MongoDB取回数据。这些数据花费的时间太长,无法返回到App.js文件。

另外,顺便说一句,我意识到在此文件中拥有Mongo连接信息是一个巨大的安全漏洞。我待会儿解决。

import {
  Stitch,
  RemoteMongoClient,
  AnonymousCredential
} from "mongodb-stitch-browser-sdk";

export function getProjects() {
  const client = Stitch.initializeDefaultAppClient("------");
  const db = client
    .getServiceClient(RemoteMongoClient.factory, "-----")
    .db("----------");
  client.auth
    .loginWithCredential(new AnonymousCredential())
    .then(() =>
      db
        .collection("--------")
        .find({}, { sort: { Project: 1 } })
        .asArray()
    )
    .then(res => {
      console.log("Found docs", res);
      console.log("[MongoDB Stitch] Connected to Stitch");
      return res;
    })
    .catch(err => {
      console.error(err);
    });
}

1 个答案:

答案 0 :(得分:0)

我认为在您的getProjects()服务中增加收益将解决您的问题。

import {
  Stitch,
  RemoteMongoClient,
  AnonymousCredential
} from "mongodb-stitch-browser-sdk";

export function getProjects() { //add async if you need to await in func body
  const client = Stitch.initializeDefaultAppClient("------");
  const db = client
    .getServiceClient(RemoteMongoClient.factory, "-----")
    .db("----------"); // if these above are async, then await them as well.

    // added return keyword here
    return client.auth // should return Promise to await in your component
    .loginWithCredential(new AnonymousCredential())
    .then(() =>
      db
        .collection("--------")
        .find({}, { sort: { Project: 1 } })
        .asArray()
    )
    .then(res => {
      console.log("Found docs", res);
      console.log("[MongoDB Stitch] Connected to Stitch");
      return res;
    })
    .catch(err => {
      console.error(err);
    });
}

编辑1:

对于重构,我认为将redux和redux-saga配对将给您很好的关注点分离,并且如果您打算这样做的话,也可以轻松编写测试。 但总的来说,我认为上述调整至少可以解决您的问题。