Реакция - Async / Await, похоже, не ждет - PullRequest
0 голосов
/ 17 января 2019

Ранее я публиковал эту проблему в сообщении об ошибке «Невозможно прочитать свойство« данные »из неопределенного». Но в процессе копания в течение нескольких часов я обнаружил, что моя проблема действительно сводится к тому, что моя «асинхронность / ожидание», похоже, не такова. , , , в ожидании! И да, я проверил несколько других версий этого вопроса, которые уже были заданы здесь. :)

Я создаю форму React, в которой будет несколько раскрывающихся списков, заполненных данными из MongoDB. Я новичок в React и новичок в MongoDB.

Мне удалось успешно вывести данные в раскрывающийся список, просто поместив весь код в один файл. Теперь я пытаюсь начать рефакторинг кода, правильно разделив части на отдельные файлы. И вот тут я столкнулся с проблемой «задержки данных».

Когда «componentDidMount» вызывает функцию «fetchProjects», эта функция отправляет и получает список проектов из MongoDB с помощью функции «getProjects» в файле «projects services». Когда console.log в «fetchProjects» запускается, он возвращается как неопределенный. Но затем, после того, как набор данных возвращается как неопределенный (и выдает ошибки), я получаю консольный журнал массива объектов проектов из функции «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 голосов
/ 17 января 2019

Я думаю, добавление возврата в ваш 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 даст вам очень хорошее разделение задач и позволит легко написать тест, если вы планируете это сделать. Но в целом, я думаю, что эта настройка, по крайней мере, может решить вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...