![](/img/trans.png)
[英]Nesting firestore onSnapshot listeners in react-native?
[英]How does a Firestore onSnapshot listens for changes in React-Native?
我在多个地方看到人们将侦听器代码放在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
只被调用一次? 注意:当屏幕 state 设置为 7 时,我只在听 Firestore。
您的componentDidMount
确实只调用了一次,但是您在其中附加了一个永久侦听器。 因此,您在onSnapshot.next
中指定的处理程序会立即使用数据库中的初始数据调用,之后每次匹配查询的数据发生更改。
解决方案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 和 refreshPatients。
解决方案 2:由于您使用的是 class 组件,因此可以使用 setState 回调。
this.setState({screen: newValue}, doSomethingNew);
doSomethingNew(){
if (this.state.screen === 7) {
// your code goes here
}
}
使用newValue
更新screen
值后触发回调函数(此处为doSomethingNew
)。
解决方案3:如果转换成function组件,可以使用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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.