我已经在很多地方看到人们将侦听器代码放在componentDidMount
内,但是我想知道它是如何工作的,因为componentDidMount
仅被调用一次,因此,它应该只获取一次。当Firestore中发生更改时,如何再次获取?
示例代码:
componentDidMount() {
if(this.state.screen === 7){
var query = firestore().collection('Collection').doc().collection('subcollection');
query = query.where('act', '==', 1);
query = query.where('city', '==', this.state.selected_city);
query = query.orderBy('update_time', 'desc');
query = query.limit(10);
query.onSnapshot({
error: (e) => this.setState({ errorMessage: e, refreshingPatients: false }),
next: (querySnapshot) => {
var dataSource = querySnapshot.docs.map(doc => { return { ...doc.data(), doc_id: doc.id } });
var lastVisiblePatient = dataSource[dataSource.length - 1].doc_id;
this.setState({
dataSource: dataSource,
lastVisiblePatient: lastVisiblePatient,
refreshingPatients: false,
});
},
});
}
}
编辑:添加了示例代码。我想一直听Firestore DB的更改。那是正确的方法吗?如果是,该方法如何工作,因为componentDidMount
仅被调用一次?
注意:我仅在屏幕状态设置为7时收听Firestore。
答案 0 :(得分:1)
您的componentDidMount
实际上只被调用过一次,但是您在其中附加了永久侦听器。因此,您将在onSnapshot.next
中指定的处理程序立即与数据库中的初始数据一起调用,此后每次与查询匹配的数据更改时都将调用。
答案 1 :(得分:0)
解决方案1: 阅读代码中的注释。
componentDidUpdate(prevState, prevProps) {
if(prevState !== this.state.screen && this.state.screen === 7) {
var query = firestore().collection('Collection').doc().collection('subcollection');
query = query.where('act', '==', 1);
query = query.where('city', '==', this.state.selected_city);
query = query.orderBy('update_time', 'desc');
query = query.limit(10);
query.onSnapshot({
error: (e) => this.setState({ errorMessage: e, refreshingPatients: false }),
next: (querySnapshot) => {
var dataSource = querySnapshot.docs.map(doc => { return { ...doc.data(), doc_id: doc.id } });
var lastVisiblePatient = dataSource[dataSource.length - 1].doc_id;
this.setState({
// you are not updating screen so it is always 7
// if you update other state variables, it will trigger ComponentDidUpdate again,
// and again and again and again
dataSource: dataSource,
lastVisiblePatient: lastVisiblePatient,
refreshingPatients: false,
});
},
});
}
}
通过添加prevState !== this.state.screen
,可以防止每次更新其他状态时都触发componentDidUpdate
。
像dataSource,lastVisiblePatient和refreshingPatients。
解决方案2:由于您使用的是类组件,因此可以使用setState回调。
this.setState({screen: newValue}, doSomethingNew);
doSomethingNew(){
if (this.state.screen === 7) {
// your code goes here
}
}
在使用doSomethingNew
更新了screen
值之后触发了回调函数(此处为newValue
)。
解决方案3::如果转换为功能组件,则可以使用useEffect
依赖项。
const [screen, setScreen] = useState(initialValue);
useEffect(() => {
if (screen === 7) {
//do something here
}
}, [screen]); // adding screen as a dependency means this useEffect is triggered only when screen value is changed.