简体   繁体   English

为什么我的react native函数总是返回undefined?

[英]Why does my react native function always return undefined?

I am using react native and I have just migrated some database functions to a individual file, instead of just having them in the files where I need them (I have started needing to use the same functions in multiple files, and I'd rather have them all in one place). 我正在使用react native,我只是将一些数据库函数迁移到了一个单独的文件中,而不是仅仅将它们存储在需要它们的文件中(我已经开始需要在多个文件中使用相同的函数,我宁愿拥有他们都放在一个地方)。 The problem is, the function that is supposed to compare a one time key with one in the database, always returns undefined . 问题是,应该将一个时间键与数据库中的一个时间键进行比较的函数始终返回undefined

I have tried returning functions instead of booleans, and have attempted to use "async/await" keywords (which I know very little about). 我尝试返回函数而不是布尔值,并尝试使用“异步/等待”关键字(对此我了解甚少)。

Here is my code... 这是我的代码...

/project/src/components/Database.js /project/src/components/Database.js

var firebase = require('firebase');

if (!firebase.apps.length) {
    firebase.initializeApp({
        apiKey: "key",
        authDomain: "domain",
        databaseURL: "url",
        storageBucket: "bucket",
    });
}

class Database {
    constructor() {
      this.codesRef = firebase.database().ref('codes');
    }
    isValidCode(text) {
        let codeIsFound = false;
        let identifier = "";
        this.codesRef.once('value', (db_snapshot) => {
          db_snapshot.forEach((code_snapshot) => {
            //console.log(text, code_snapshot.val().value, text == code_snapshot.val().value);
            if (text == code_snapshot.val().value) {
              codeIsFound = true;
              identifier = code_snapshot.key;
            }
          });
          //console.log(codeIsFound); // this is correct
          return codeIsFound; // this always returns undefined
        });
    };
}

module.exports = Database;

/project/src/components/forms/KeyForm.js /project/src/components/forms/KeyForm.js

import React from 'react';
import {
  StyleSheet,
  View,
  TextInput,
} from 'react-native';

import { withNavigation } from 'react-navigation';

import database from '../Database.js';

const db = new database();


class LoginForm extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={styles.input}
          placeholder="Access Code"
          returnKeyType="go"
          onSubmitEditing={text => {console.log(db.validCode(text.nativeEvent.text))}} // "undefined"
          autoCapitalize="none"
          autoCorrect={false}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({\
  // yay styles :)
});

export default withNavigation(LoginForm);

Whenever I put a return statement after the firebase "once" function, it does return a boolean, but for some reason it is always false. 每当我在firebase“ once”函数之后放置return语句时,它都会返回布尔值,但是由于某种原因,它始终为false。 Any help is greatly appreciated! 任何帮助是极大的赞赏!

Addressing this: Whenever I put a return statement after the firebase "once" function, it does return a boolean, but for some reason it is always false. 解决这个问题: 每当我在firebase“ once”函数之后放置一个return语句时,它都会返回一个布尔值,但是由于某种原因,它始终为false。

By removing the .once() method code, you can clearly see why this is the case. 通过删除.once()方法代码,您可以清楚地了解为什么是这种情况。 The code executes exactly as if it were written like below. 该代码的执行方式与下面的代码完全相同。 Due to the async nature of the .once() method, the return statement executes prior to the .once() resolving (completing). 由于.once()方法的异步性质, return语句在.once()解析(完成)之前执行。

isValidCode(text) {
  let codeIsFound = false;
  let identifier = "";
  // .once() goes here
  return codeIsFound;
};

Your instinct was a good one about async/await. 您的本能是关于异步/等待的良好本能。 To fix your issue, do this: 要解决您的问题,请执行以下操作:

async isValidCode(text) {
  let codeIsFound = false;
  let identifier = "";
  let db_snapshot = await this.codesRef.once('value');
   db_snapshot.forEach(code_snapshot => {
       if (text == code_snapshot.val().value) {
          codeIsFound = true;
          identifier = code_snapshot.key;
        }
   });
   return codeIsFound; 
};

Then, the function will return a promise that will be resolved (or rejected). 然后,该函数将返回一个将被解决(或拒绝)的promise。 So to use this code do: 因此,要使用此代码,请执行以下操作:

isValidCode('something').then(result => {
   /* use result here */
};

once() returns a Promise<DataSnapshot> , which means it is asynchronous and you cannot return a value from an asynchronous method. once()返回Promise<DataSnapshot> ,这意味着它是异步的,并且您不能从异步方法返回值。

To solve your problem, you can do the following: 要解决您的问题,您可以执行以下操作:

    isValidCode(text) {
    let codeIsFound = false;
    let identifier = "";
    this.codesRef.once('value', (db_snapshot) => {
      db_snapshot.forEach((code_snapshot) => {
        //console.log(text, code_snapshot.val().value, text == code_snapshot.val().value);
        if (text == code_snapshot.val().value) {
          codeIsFound = true;
          identifier = code_snapshot.key;
          takeValue(codeIsFound);
        }
      });
    });
};

takeValue(value){
 console.log(value) //true
}

Here you create a new method inside once() and then add the value as a argument. 在这里,您可以在once()内部创建一个新方法,然后将该值添加为参数。

As per @randy casburn problem is same. 按照@randy casburn的问题是相同的。 Just modifying solution given by @randy. 只需修改@randy提供的解决方案。

    async isValidCode(text) { let codeIsFound = false; let identifier = ""; if(await this.codesRef.once function call ) {
Return true;
} else {return false;} };

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

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