我目前正在开发一个笔记本风格的应用程序,其中的数据是通过 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>
);
}
}
}
在我当前的代码中,只有未加密的笔记本正在渲染。那么我该如何重组我的组件,以便在解密所有数据后我可以呈现我的最终组件 block 。
最佳答案
this.setState()
在 data.map()
解析之前被触发。
Promise.all()
可用于运行
和等待
promise
的数组
的解析。
请参阅下面的实际示例。
// 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'))
<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>
关于javascript - 长时间运行作业后渲染组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49625093/