React - 等待数据从 API 获取
React - await until data fetches from API
我正在尝试获取一些 JSON 数据,并且我已使用 async/await 来暂停执行,直到数据加载准备就绪。但是 React 似乎完全忽略了这一点并尝试渲染组件。我在下面编写了简化代码来进一步测试,setTimeout
正在模仿 API 调用延迟。
console.log('global');
var index ="Data not loaded";
(async function fetchDataAsync(){
console.log('async start');
//mimcs loading data from API calls
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Data loaded!"), 1000)
});
var index = await promise;
console.log('async end');
console.log(index);
})();
class App extends React.Component {
constructor(props){
super(props);
this.state={
randomIndex:0
}
console.log('constructor');
}
render(){
console.log('render');
return (
<div >
<p>{index}</p>
</div>
);
}
}
输出显示数据未加载,控制台显示如下
全球
异步启动
构造函数
渲染
异步结束
数据已加载!
这是 React 应该如何工作还是我在这里遗漏了什么?什么是放置 API 调用的最佳位置,以便它保证在组件安装之前加载数据。
谢谢
问题是异步函数不会阻止 同步 处理该函数出现的代码。我的意思是,您的代码运行顺序是:
- 开始 运行
async
函数直到 await
- 创建
App
class
- ...在
App
class 之后您还没有显示的任何其他内容;我猜你在某处使用 App
...
- 顶级代码完成
- 计时器触发
- 等待计时器结算的承诺
asycn
函数调用创建的 promise 结算
注意 2-4 发生在 5-7 之前。
你想要做的是
在获得数据之前不要使用 App
,或者
给App
一个"waiting"它在等待数据时呈现的状态
这些解决方案中的每一种都适用于不同的情况,因此您需要选择适合您情况的解决方案。
这不是 React 的做事方式,在渲染之前等待数据到来。
你的代码应该是反应式的,它应该触发数据到达的组件。
这里是你如何做到这一点
class App extends React.Component {
constructor(props){
super(props);
this.state={
randomIndex:0,
data: '',
loading: false
}
console.log('constructor');
}
fetchDataAsync = async () => {
console.log('async start');
this.setState({ loading: true });
//mimcs loading data from API calls
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Data loaded!"), 1000)
});
var data = await promise;
console.log('async end');
console.log(data);
this.setState({ loading: false, data });
}
render(){
console.log('render');
const { loading, data } = this.state;
if(loading) return (<div className="loader">Loading ... </div>);
if (!loading && data) {
return (
<div >
<p>{data}</p>
</div>
);
}
return null;
}
}
我正在尝试获取一些 JSON 数据,并且我已使用 async/await 来暂停执行,直到数据加载准备就绪。但是 React 似乎完全忽略了这一点并尝试渲染组件。我在下面编写了简化代码来进一步测试,setTimeout
正在模仿 API 调用延迟。
console.log('global');
var index ="Data not loaded";
(async function fetchDataAsync(){
console.log('async start');
//mimcs loading data from API calls
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Data loaded!"), 1000)
});
var index = await promise;
console.log('async end');
console.log(index);
})();
class App extends React.Component {
constructor(props){
super(props);
this.state={
randomIndex:0
}
console.log('constructor');
}
render(){
console.log('render');
return (
<div >
<p>{index}</p>
</div>
);
}
}
输出显示数据未加载,控制台显示如下
全球
异步启动
构造函数
渲染
异步结束
数据已加载!
这是 React 应该如何工作还是我在这里遗漏了什么?什么是放置 API 调用的最佳位置,以便它保证在组件安装之前加载数据。 谢谢
问题是异步函数不会阻止 同步 处理该函数出现的代码。我的意思是,您的代码运行顺序是:
- 开始 运行
async
函数直到await
- 创建
App
class - ...在
App
class 之后您还没有显示的任何其他内容;我猜你在某处使用App
... - 顶级代码完成
- 计时器触发
- 等待计时器结算的承诺
asycn
函数调用创建的 promise 结算
注意 2-4 发生在 5-7 之前。
你想要做的是
在获得数据之前不要使用
App
,或者给
App
一个"waiting"它在等待数据时呈现的状态
这些解决方案中的每一种都适用于不同的情况,因此您需要选择适合您情况的解决方案。
这不是 React 的做事方式,在渲染之前等待数据到来。
你的代码应该是反应式的,它应该触发数据到达的组件。
这里是你如何做到这一点
class App extends React.Component {
constructor(props){
super(props);
this.state={
randomIndex:0,
data: '',
loading: false
}
console.log('constructor');
}
fetchDataAsync = async () => {
console.log('async start');
this.setState({ loading: true });
//mimcs loading data from API calls
let promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Data loaded!"), 1000)
});
var data = await promise;
console.log('async end');
console.log(data);
this.setState({ loading: false, data });
}
render(){
console.log('render');
const { loading, data } = this.state;
if(loading) return (<div className="loader">Loading ... </div>);
if (!loading && data) {
return (
<div >
<p>{data}</p>
</div>
);
}
return null;
}
}