我目前正在开发一款笔记本式应用,其中数据通过ajax加载。其中一些笔记本电脑是加密的。所以我必须在最终渲染之前解密这些数据。这是我目前的组成部分:
import React from "react";
import ReactDOM from "react-dom";
import "regenerator-runtime/runtime";
class Notebooks extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
data: ""
}
}
loadData() {
$.ajax("/notebook/", {
contentType: "application/json",
success: function (data) {
let bunny = [];
data.map(async (hiren, index) => {
let plaintext = {};
if (hiren["fields"]["encrypted"]) {
let data = {};
let name_options = {
message: openpgp.message.readArmored(hiren["fields"]["name"]),
passwords: [sessionStorage.getItem("key")],
format: "utf8"
};
let description_options = {
message: openpgp.message.readArmored(hiren["fields"]["description"]),
passwords: [sessionStorage.getItem("key")],
format: "utf8"
};
let _name = await openpgp.decrypt(name_options);
let _description = await openpgp.decrypt(description_options);
data["pk"] = hiren["pk"];
data["fields"] = { "name": _name.data, "description": _description.data };
bunny.push(data);
} else {
plaintext["pk"] = hiren["pk"];
plaintext["fields"] = {
"name": hiren["fields"]["name"],
"description": hiren["fields"]["description"]
};
bunny.push(plaintext);
}
});
this.setState({ data: bunny });
this.setState({ loading: false });
}.bind(this),
error: function (data) {
console.error(data);
}
});
componentDidMount(){
this.loadData();
}
final_component(){
// some jsx
}
render() {
if (this.state.loading) {
return (
<div>Loading...</div>
)
}
return (
<div>{this.final_component()}</div>
);
}
}
}
在我目前的代码中,只有未加密的笔记本正在渲染。那么如何重新组织我的组件,以便在解密所有数据后,我可以渲染我的最终组件块。
答案 0 :(得分:2)
this.setState()
结算之前, data.map()
被解雇了。
Promise.all()
可用于run
和await
arrays
promises
的解析。
请参阅下面的实际示例。
// Load Chunk.
const loadChunk = (x) => new Promise(resolve => setTimeout(() => resolve(`chunk ${x}`), 1000))
// Load Comp.
class LoadComp extends React.Component {
// State.
state = {
loading: true,
data: false
}
// Render.
render() {
if (this.state.loading) return <div>Loading ..</div>
return <div>{this.state.data.map((x, i) => <div key={i}>{x}</div>)}</div>
}
// Did Mount.
componentDidMount() {
this.fetchData()
}
// Fetch Data.
fetchData = () => Promise.all([1, 2, 3, 4].map(x => loadChunk(x))).then(data => this.setState({data, loading: false}))
}
// Mount.
ReactDOM.render(<LoadComp/>, document.querySelector('#root'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<div id="root"></div>
&#13;