繁体   English   中英

Firestore onSnapshot 如何监听 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM