【问题标题】:ReactJS error - “Cannot read property 'data' of undefined”ReactJS 错误 - “无法读取未定义的属性‘数据’”
【发布时间】:2019-02-03 17:27:43
【问题描述】:

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

我一开始只是尝试创建一个带有一个下拉菜单的基本页面。一旦我做对了,我就可以继续添加其他下拉菜单。

我只需将所有代码塞入一个文件即可成功地将数据放入下拉列表中。现在,我正在尝试通过将部分正确拆分为单独的文件来开始重构代码。这就是我遇到问题的地方。

我已将我的 MongoDB 数据提取(使用 Mongo Stitch)拆分为一个单独的“服务”文件。而且我仍在通过那个新的服务文件获取数据。但是,当我尝试将该服务文件数据拉入我的主 (App.js) 页面时,我收到“无法读取未定义的属性‘数据’”错误。所以,很明显,我试图将数据拉入我的 App.js 文件的方式是错误的。任何人都可以提供任何专家见解,我将不胜感激!

这是我的 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);
    });
}

【问题讨论】:

  • 快速查看您的代码,您在 this.setState 中设置了大写 P 的项目

标签: reactjs


【解决方案1】:

您似乎正在使用destructuringgetProjects() 返回的对象中获取data 成员,但getProjects() 没有返回具有此类成员的对象。

也许你想把它改成下面这样 -

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

此外,就像提到的@Win 一样,projects 中的P 在您的状态初始化时大写,但之后不会大写。你可能想解决这个问题。

【讨论】:

  • 感谢您的建议,tkore!我做了你推荐的改变,我想我正在取得进展。我现在收到“无法读取未定义的属性‘地图’”的错误。因此,看起来它现在正在传递数据,但无法执行 map 方法。对下一步有什么想法吗?
  • @JoelMorgan 太好了,很高兴我能帮上忙。关于您的第二个问题 - 发生这种情况是因为在您运行代码时,this.state.projects 未被识别为数组。在你的状态初始化中替换你的大写 P 应该可以解决它。
  • 如果没有解决,如果this.state.projects未定义,则使用(this.state.projects || []).map回退到一个空数组
【解决方案2】:

我发现我的问题归结为我的数据没有尽快到达 componentDidMount 生命周期挂钩。因此,当流程继续进行时,“项目”数据仍未定义。换句话说,我的“异步/等待”不是 . . .等待中!

我将发布一个单独的问题,关于如何使异步等待直到我真正取回数据。但同样,只是想将此标记为“已解决”,因为问题并未发生在数据获取的下游。数据只是没有很快到达。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2018-07-25
    • 2018-09-10
    • 2021-05-04
    相关资源
    最近更新 更多