首页 > 解决方案 > 来自另一个组件的(react-native)函数不会返回我的值

问题描述

我正在构建带有firebase调用的类。当我第一次构建我的类时,我直接调用了同一个类(以获取一些数据)并且它以这种方式工作得非常好。

然后,我决定为数据库调用创建专用类,并使用完全相同的代码从我的 firebase 数据库中获取数据,经过进一步调查,我似乎遇到了从一个类返回到另一个类的值的问题(这就是为什么我编辑我的帖子并更改标题)。

这是我的主要课程:

import React from 'react'
import { StyleSheet, Text, Image, View, TouchableOpacity, Platform } from 'react-native'
import { Ionicons } from '@expo/vector-icons'
import firebase from '../config/Firebase'

import GlobalAccess from '../dbaccess/GlobalData.js'
import StuffAccess from '../dbaccess/StuffData.js'
import MoneyAccess from '../dbaccess/MoneyData.js'

class Home extends React.Component {

    constructor(props) {
        super(props)
        this._goToSettings = this._goToSettings.bind(this)
        this.ref = firebase.firestore().collection('globalData')
// as said, I first put this.ref to call directly firebase from my main class and it's working fine

        this.state = { 
            totalMoney: 0,
            totalQuantity: 0,
            isLoading: true
        }
    }

    _updateNavigationParams() {
        const navigation = this.props.navigation

        let settingsIconName
        (Platform.OS === 'android') ? settingsIconName = 'md-settings' : settingsIconName = 'ios-settings'

        navigation.setOptions({
            headerRight: () => <TouchableOpacity style={styles.settings_touchable_headerrightbutton}
                            onPress={() => this._goToSettings()}>
                                <Ionicons name={settingsIconName} style={styles.settings_image} />
            </TouchableOpacity>
        })
    }

    componentDidMount(){
        this._updateNavigationParams()
        //this._getData()
        this.totalStuff = StuffAccess.totalStuff()
        }

这是 StuffData.js 的(总)代码

// dbaccess/StuffAccess.js

import firebase from '../config/Firebase'

class StuffAccess {

    constructor() {
        this.stuff = firebase.firestore().collection('stuff');
    }

    getStuffData(){
        const stuffList = [];

        let query = this.stuff.get()
        .then(snapshot => {
            if (snapshot.empty) {
            console.log('No stuff data.');
            return stuffList
            }  

            snapshot.forEach(stuff => {

                const { title, quantity, date, people, type } = stuff.data()
                stuffList.push({
                    key: stuff.id,
                    title,
                    quantity,
                    date: (date.toString().length > 0) ? new Date(date.seconds*1000) : new Date(),
                    people,
                    type
                })
            })
        })
        .catch(err => {
            console.log('Error getting stuff data : ', err);
        });

        console.log('stufflist : ' + stuffList)
        return stuffList
    }

    totalStuff() {
        let totalStuff = 0;

        let query = this.stuff.get()
        .then(snapshot => {
            if (snapshot.empty) {
            console.log('No stuff data.');
            return stuffList
            }  

            snapshot.forEach(stuff => {

                totalStuff += stuff.data().quantity

            })
            console.log('totalStuff : ' + totalStuff)
            return totalStuff
        })
        .catch(err => {
            console.log('Error getting stuff data : ', err);
        });
    }

    addStuff(title, quantity, date, people, type) {
        // Ajout du prêt d'objet en BDD
        this.stuff.add({
            title: title,
            quantity: quantity,
            date: date,
            people: people,
            type: type
        }).then((docRef) => {
            console.log("stuff added to db")
        })
        .catch((error) => {
            console.error("Error adding stuff : ", error);
        });
    }

    deleteStuff(key) {
        this.stuff.doc(key).delete()
        .catch((error) => {
            console.error("Error deleting stuff : ", error);
        });
    }
}

const stuffAccess = new StuffAccess();
export default StuffAccess

我的返回函数似乎没有向我的 Home 类返回任何内容。 this.state.totalStuff在函数undefined内调用 Home.js 之后ComponentDidMount()

标签: javascriptfirebasereact-nativegoogle-cloud-firestore

解决方案


好的,所以在网络中深入挖掘之后,我的眼睛受伤了,我明白了我的问题出在哪里。

因此,正如最初发现的那样,这是我尝试在我的函数之间传递数据的时候。

我理解 javascript 的工作方式,尤其是类不能(至少像我试图做的那样直接)将动态内容从一个发送到另一个。

所以解决办法就是使用async()方法。

我必须像这样编写调用我的数据库的类(看看getStuffData()ortotalStuff()函数:

// dbaccess/StuffData.js

import firebase from '../config/Firebase'

export default class StuffData {

    constructor() {
        this.stuff = firebase.firestore().collection('stuff');

    }

    // async function puisque react fonctionne de la sorte. Il ne peut donc transmettre de façon dynamique des données
    // entre les classes (sinon il pourrait attendre indéfiniment). Il faut ensuite récupérer la promise de l'autre côté.
    async getStuffData() {
        const stuffList = []

        let query = await this.stuff.get()
        .then(snapshot => {
            if (snapshot.empty) {
            console.log('No stuff data.');
            return stuffList
            }  

            snapshot.forEach(stuff => {

                const { title, quantity, date, people, type } = stuff.data()
                stuffList.push({
                    key: stuff.id,
                    title,
                    quantity,
                    date: (date.toString().length > 0) ? new Date(date.seconds*1000) : new Date(),
                    people,
                    type
                })
            })
        })
        .catch(err => {
            console.log('Error getting stuff data : ', err);
        });

        return stuffList
    }

    async totalStuff() {
        let totalQuantity = 0

        let query = await this.stuff.get()
        .then(snapshot => {
            if (snapshot.empty) {
            console.log('No stuff data.')
            return [];
            }  

            snapshot.forEach(stuff => {
                totalQuantity += parseInt(stuff.data().quantity)
            })
        })
        .catch(err => {
            console.log('Error getting stuff data : ', err);
        })
        return totalQuantity
    }

    addStuff(title, quantity, date, people, type) {
        // Ajout du prêt d'objet en BDD
        this.stuff.add({
            title: title,
            quantity: quantity,
            date: date,
            people: people,
            type: type
        }).then((docRef) => {
            console.log("stuff added to db")
        })
        .catch((error) => {
            console.error("Error adding stuff : ", error);
        });
    }

    deleteStuff(key) {
        this.stuff.doc(key).delete()
        .catch((error) => {
            console.error("Error deleting stuff : ", error);
        });
    }
}

并调用它并将其读Promise入我的其他课程,如下所示:

_getData() {
        let myStuff = new StuffData();
        myStuff.totalStuff().then(val => { this.setState({
            totalQuantity: val
            })
        })
        .catch(error => {
            console.error(error)
        })

        let myMoney = new MoneyData();
        myMoney.totalMoney().then(val => { this.setState({
            totalMoney: val
            })
        })
    }

这解决了我的问题。


推荐阅读