React——Async/Await 好像不是在等待
React – Async / Await doesn’t seem to be waiting
我之前在“无法读取未定义的属性 'data'”的错误消息下发布了这个问题。但是在深入研究几个小时的过程中,我发现我的问题实际上归结为我的“async/await”似乎不是。 . . .等待!是的,我确实检查了这里已经问过的这个问题的其他几个版本。 :)
我正在构建一个 React 表单,其中包含多个下拉框,其中填充了来自 MongoDB 的数据。我是 React 的新手,也是 MongoDB 的初学者。
通过将所有代码塞进一个文件中,我已经能够成功地将数据放入下拉列表中。现在,我正尝试通过将代码块适当地拆分成单独的文件来开始重构代码。这就是我 运行 进入这个“数据延迟”问题的地方。
当“componentDidMount”调用“fetchProjects”函数时,该函数会使用“项目服务”文件中的“getProjects”函数从 MongoDB 中获取项目列表。当“fetchProjects”运行s 中的 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);
});
}
我认为在您的 getProjects()
服务中添加 return 可以解决您的问题。
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 会给你很好的关注点分离,如果你打算这样做的话,也是一种轻松编写测试的方法。
但总的来说,我认为上面的这个调整至少可以解决你的问题。
我之前在“无法读取未定义的属性 'data'”的错误消息下发布了这个问题。但是在深入研究几个小时的过程中,我发现我的问题实际上归结为我的“async/await”似乎不是。 . . .等待!是的,我确实检查了这里已经问过的这个问题的其他几个版本。 :)
我正在构建一个 React 表单,其中包含多个下拉框,其中填充了来自 MongoDB 的数据。我是 React 的新手,也是 MongoDB 的初学者。
通过将所有代码塞进一个文件中,我已经能够成功地将数据放入下拉列表中。现在,我正尝试通过将代码块适当地拆分成单独的文件来开始重构代码。这就是我 运行 进入这个“数据延迟”问题的地方。
当“componentDidMount”调用“fetchProjects”函数时,该函数会使用“项目服务”文件中的“getProjects”函数从 MongoDB 中获取项目列表。当“fetchProjects”运行s 中的 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);
});
}
我认为在您的 getProjects()
服务中添加 return 可以解决您的问题。
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 会给你很好的关注点分离,如果你打算这样做的话,也是一种轻松编写测试的方法。 但总的来说,我认为上面的这个调整至少可以解决你的问题。