在从Firebase中读取数据时,我似乎遇到了setState
的某种竞争条件。在加载组件时,将为与表clients
中的客户端记录一样多的客户端记录调用侦听器child_added
,但只有最后一个客户端记录实际存储在使用setState
的状态中。我知道这与setState中的延迟有关,因为它只在周期结束时才起作用,所以多个setState调用存在竞争条件。如何修复此问题,以使所有客户端记录都正确存储在this.state.clients
中
class ClientsTable extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
clients: [],
};
}
componentWillMount(){
let clientsRef = fire.database().ref('clients').orderByKey().limitToLast(100);
clientsRef.on('child_added', snapshot => {
let client = snapshot.val();
client.id = snapshot.key
this.setState({ clients: [client].concat(this.state.clients) })
})
}
}
发布于 2018-06-09 05:34:02
不应该有任何争用条件,因为setState()
在每次调用时都会将更改入队,在这种情况下,每个由child_added
事件产生的client
快照都包括现有的client
和添加的新client
。
真正的问题可能只是你的setState()
语法,它可能每次都会改变/恢复this.state.clients
。相反,可以尝试使用spread syntax
...
将client
对象附加到this.state.clients
,并以不可变的方式更新/合并this.state
。
class ClientsTable extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
clients: []
};
}
componentWillMount(){
const clientsRef = fire.database().ref('clients').orderByKey().limitToLast(100);
clientsRef.on('child_added', snapshot => {
const client = { ...snapshot.val(), id: snapshot.key };
this.setState({
...this.state,
clients: [...this.state.clients, client]
});
});
}
}
使用personal Firebase项目,我能够将每个项目转换为等同于this.state.clients
的内容,并相应地在componentDidMount
或componentWillMount
中显示这些内容。如果你愿意,你可以创建一个模拟数据/结构与你的实际项目相匹配的虚拟Firebase项目,如果它仍然不能工作,就生成一个StackBlitz。
希望这能有所帮助!
https://stackoverflow.com/questions/50768061
复制相似问题