简体   繁体   English

来自另一个组件的 (react-native) 函数不会返回我的值

[英](react-native) function from another component won't return my value

I'm building class with firebase calls in it.我正在构建带有 firebase 调用的类。 When I first built my class I made my call directly into the same class (to get some data) and it's working perfectly fine this way.当我第一次构建我的类时,我直接将我的调用发送到同一个类中(以获取一些数据),并且它以这种方式工作得非常好。

I then decided to create dedicated class to database calls, and I use the exact same code to get my data from my firebase db and after further investigation it seems that I got a problem with the value returned from one class to another (and that's why I edit my post and change the title).然后我决定为数据库调用创建专用的类,我使用完全相同的代码从我的 firebase 数据库中获取我的数据,经过进一步调查,似乎我从一个类返回到另一个类的值有问题(这就是为什么我编辑了我的帖子并更改了标题)。

Here is my main class :这是我的主要课程:

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()
        }

Here is the (total) code for StuffData.js这是 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

My return function does not seem to return anything to my Home class.我的返回函数似乎没有向我的 Home 类返回任何东西。 this.state.totalStuff is undefined after the call in Home.js within the ComponentDidMount() function. this.state.totalStuff在 Home.js 中的ComponentDidMount()函数内调用后undefined

Ok so after digging so deep within the web I have my eyes hurting I understood where was my problem.好吧,在网上挖得这么深后,我的眼睛受伤了,我明白我的问题出在哪里了。

So as firstly found, it was when I tried to pass data between my functions.正如第一次发现的那样,当我试图在我的函数之间传递数据时。

I understood the way that javascript works and especially that the classes could not (at least directly as I was trying to do) send dynamic content from one to another.我理解 javascript 的工作方式,尤其是这些类不能(至少像我试图这样做的那样直接)将动态内容从一个发送到另一个。

So the solution is to use the async() method.所以解决方案是使用async()方法。

I have to write the class calling my db like this (take a look at getStuffData() or totalStuff() functions :我必须像这样编写调用我的数据库的类(看看getStuffData()totalStuff()函数:

// 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);
        });
    }
}

And call it and read the Promise into my other class, like this :并调用它并将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
            })
        })
    }

This solved my problem.这解决了我的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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