javascript - 渲染在异步方法结束之前运行。如何从我的异步方法将道具传递给组件?
问题描述
我需要将数据从 firestore 传递到我的组件中。但是请求是异步的,所以在我从请求中获取数据之前,当我的渲染方法运行时,我遇到了问题。因此,当渲染运行时,pops 值为 Null,因为尚未定义状态。由于某种原因,组件也会渲染两次。有没有更好的方法来处理异步的东西?
已经尝试过将请求放到更高位置的firestore(index.js)并将数据向下传递给应用程序。试图在渲染方法中发出请求。试图将请求放在异步函数中并在构造函数中调用它以在那里设置状态。与调用异步方法相同。
class App extends Component {
constructor(props) {
super(props);
this.giveUsername = this.giveUsername.bind(this);
const userId = firebase.auth().currentUser.email;
this.giveUsername(userId);
}
async giveUsername(userId){
let username;
await firebase.firestore().collection('users').where('email', '==', userId).get().then((snapshot) =>{
snapshot.docs.forEach(doc =>{
console.log(`doc.data().username - ${doc.data().username}`);
username = doc.data().username;
});
});
this.setState( {
userId : userId,
username : username
});
}
render() {
return (
<div className='App'>
<Header username={this.state.username}/>
<NewTask userId={this.state.userId}/>
<TaskList userId={this.state.userId}/>
</div>
);
}
}
解决方案
您应该初始化state
构造函数中loading
的
constructor(props) {
super(props);
state = {
userId : 0,
username : '',
loading: true
}
}
当数据准备好时设置为loading
:false
async giveUsername(userId){
...
this.setState( {
userId : userId,
username : username,
loading: false
});
}
使成为 :
render() {
return (
<div className='App'>
{this.state.loading
? <span>Loading ... </span>
: (
<Header username={this.state.username}/>
<NewTask userId={this.state.userId}/>
<TaskList userId={this.state.userId}/>
)
}
</div>
);
}
组件呈现双胞胎的原因是因为它state
正在发生变化,这是正常的。
推荐阅读
- reactjs - 如何将图像插入状态(React)
- reactjs - 在 React Bootstrap 中居中模式标题和按钮
- javascript - 有没有办法使用 HTML/CSS/JavaScript 使用较大图像的坐标(在第二个图像下)重叠 2 个图像?
- c# - 读取 JSON 文件时 Keyvaluepair 值为 0
- mysql - 在 SQL 查询中获取列定义不明确的错误
- node.js - Nginx 代理 + NodeJS WebSocket + >17KB 消息。没有交通。谁是罪魁祸首?
- java - 随机生成对象的问题
- angular - MSAL-angular 要求额外的权限
- javascript - 日期选择器和选择的高度相同吗?
- json - flatten_json 给了我一长串列和一行而不是所需的数据框结构