我必须按下两次按钮才能从firebase实时数据库中填充反应状态



在我的react组件中,当组件挂载时,我想运行loadData((函数来填充状态中的一组people对象。

该组件称为UserDisplaySection.js

componentDidMount() {
this.loadData();
}

调用函数加载数据:

loadData = () => {
const db = fire.database();
const ref = db.ref('User');
let currentState = this.state.people;
ref.on('value', (snapshot) => {
snapshot.forEach( (data) => {
const currentStudent = data.val();
let user ={
"email" : currentStudent.Email,
"name": currentStudent.Name,
"age": currentStudent.Age,
"location": currentStudent.Location,
"course": currentStudent.Course,
"interests": currentStudent.Interests
}
currentState.push(user);
});
});
this.setState({
people: currentState
});
}

从另一个名为Home.js的组件中,我用一个按钮的切换来呈现UserDisplaySection.js,该按钮设置了一个名称为willDisplayUser的布尔值的状态,默认情况下该布尔值初始化为false。

handleDisplayUsers = e => {
e.preventDefault();
this.setState({
willDisplayUsers: !(this.state.willDisplayUsers),
});
}
render() {
return (
<div>
<button className="mainButtons" onClick={this.handleDisplayUsers}>View Users</button> <br />
{this.state.willDisplayUsers ? <UserDisplaySection/>: null}
</div>
);
}

注意:该函数可以工作,并用正确的数据填充状态,但只有在我第二次呈现UserDisplaySection.js组件之后,并且在重新加载页面之前才能完美工作。

通过执行ref.on(),您实际上是在声明一个"侦听特定位置的数据更改"的侦听器,如文档中所述。"将为初始数据触发回调,并在数据更改时再次触发"。换句话说,它与您的按钮onClick事件断开连接。

如果您想按需获取数据,即单击按钮时,您应该使用once()方法,该方法"只侦听指定事件类型的一个事件,然后停止侦听"。

问题的根源在于您在ref.on回调之外设置状态。

数据提取是异步的,稍后将执行回调。由于set状态在回调之外,因此它在注册侦听器之后立即被调用,但在数据完成获取之前。这就是为什么它在初始渲染/按钮单击时不起作用:它显示初始状态,而不是等待获取完成。

此外,使用once而不是on可能更适合您的情况。

loadData = () => {
const db = fire.database();
const ref = db.ref('User');
let currentState = this.state.people;
ref.once('value', (snapshot) => {
// callback start
snapshot.forEach( (data) => {
const currentStudent = data.val();
let user ={
"email" : currentStudent.Email,
"name": currentStudent.Name,
"age": currentStudent.Age,
"location": currentStudent.Location,
"course": currentStudent.Course,
"interests": currentStudent.Interests
}
currentState.push(user);
});
this.setState({
people: currentState
});
// callback end
});
// setState used to be here, outside of the callback
}

最新更新