Javascript 为什么我的react本机函数总是返回未定义的?
我使用的是react native,我刚刚将一些数据库函数迁移到一个单独的文件中,而不是将它们放在我需要它们的文件中(我已经开始需要在多个文件中使用相同的函数,我更希望将它们全部放在一个位置)。问题是,用于将一次性键与数据库中的一次性键进行比较的函数总是返回未定义的 我曾尝试过返回函数而不是布尔值,并尝试过使用“async/await”关键字(我对此知之甚少) 这是我的密码 /project/src/components/Database.jsJavascript 为什么我的react本机函数总是返回未定义的?,javascript,firebase,react-native,firebase-realtime-database,react-navigation,Javascript,Firebase,React Native,Firebase Realtime Database,React Navigation,我使用的是react native,我刚刚将一些数据库函数迁移到一个单独的文件中,而不是将它们放在我需要它们的文件中(我已经开始需要在多个文件中使用相同的函数,我更希望将它们全部放在一个位置)。问题是,用于将一次性键与数据库中的一次性键进行比较的函数总是返回未定义的 我曾尝试过返回函数而不是布尔值,并尝试过使用“async/await”关键字(我对此知之甚少) 这是我的密码 /project/src/components/Database.js var firebase = require('f
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;
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);
/project/src/components/forms/KeyForm.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;
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);
从“React”导入React;
进口{
样式表,
看法
文本输入,
}从“反应本机”;
从“react navigation”导入{withNavigation};
从“../database.js”导入数据库;
const db=新数据库();
类LoginForm扩展了React.Component{
建造师(道具){
超级(道具);
}
render(){
返回(
{console.log(db.validCode(text.nativeEvent.text))}/“未定义”
autoCapitalize=“无”
自动更正={false}
/>
);
}
}
const styles=StyleSheet.create({\
//雅伊风格:)
});
使用导航导出默认值(LoginForm);
每当我将return语句放在firebase“once”函数之后时,它确实会返回布尔值,但由于某些原因,它总是false。非常感谢您的帮助 解决这个问题:每当我将return语句放在firebase“once”函数之后时,它确实会返回一个布尔值,但由于某些原因,它总是false
通过删除.once()
方法代码,您可以清楚地看到为什么会出现这种情况。代码的执行方式与下面编写的代码完全相同。由于.once()
方法的异步性质,return
语句在.once()
解析(完成)之前执行
isValidCode(文本){
设codeIsFound=false;
让标识符=”;
//.一旦()转到这里
找到返回码;
};
关于异步/等待,您的直觉很好。要解决问题,请执行以下操作:
async isValidCode(文本){
设codeIsFound=false;
让标识符=”;
让db_snapshot=等待这个.codesRef.once('value');
db_snapshot.forEach(代码_snapshot=>{
if(text==code_snapshot.val().value){
codeIsFound=true;
标识符=code_snapshot.key;
}
});
找到返回码;
};
然后,函数将返回一个将被解析(或拒绝)的承诺。因此,要使用此代码,请执行以下操作:
isValidCode('something')。然后(结果=>{
/*在这里使用结果*/
};
解决这个问题:每当我在firebase“once”函数后面放一个return语句时,它确实会返回一个布尔值,但由于某些原因,它总是false
通过删除.once()
方法代码,您可以清楚地看到为什么会出现这种情况。代码的执行方式与下面的编写方式完全相同。由于.once()
方法的异步性质,因此return
语句在.once()
解析(完成)之前执行
isValidCode(文本){
设codeIsFound=false;
让标识符=”;
//.一旦()转到这里
找到返回码;
};
关于async/await,您的直觉很好。要解决您的问题,请执行以下操作:
async isValidCode(文本){
设codeIsFound=false;
让标识符=”;
让db_snapshot=等待这个.codesRef.once('value');
db_snapshot.forEach(代码_snapshot=>{
if(text==code_snapshot.val().value){
codeIsFound=true;
标识符=code_snapshot.key;
}
});
找到返回码;
};
然后,函数将返回一个将被解析(或拒绝)的承诺。因此,要使用此代码,请执行以下操作:
isValidCode('something')。然后(结果=>{
/*在这里使用结果*/
};
返回一个承诺
,这意味着它是异步的,不能从异步方法返回值
要解决您的问题,您可以执行以下操作:
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
}
在这里,您可以在once()
中创建一个新方法,然后将该值作为参数添加。返回一个承诺,这意味着它是异步的,您不能从异步方法返回值
要解决您的问题,您可以执行以下操作:
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
}
在这里,您将在once()
中创建一个新方法,然后将该值作为参数添加。根据@randy casburn,问题是相同的。
只是修改@randy给出的解决方案
async isValidCode(text) { let codeIsFound = false; let identifier = ""; if(await this.codesRef.once function call ) {
Return true;
} else {return false;} };
根据@randy casburn,问题是相同的。
只是修改@randy给出的解决方案
async isValidCode(text) { let codeIsFound = false; let identifier = ""; if(await this.codesRef.once function call ) {
Return true;
} else {return false;} };
我认为这很接近,但它会导致函数返回一个“Promise”对象而不是booleanYes,当然。这就是工作原理。要使用该值,请执行以下操作:isValidCode('stuff')。然后(result=>{/*use result here*/}
这肯定更接近,但它返回object{“-LemIGLQEdkCniOFoi8d”:object{“value”:“broIMI”,},“-LemIbAmrtC9ABe9EXM2”:对象{“值”:“7xMbif”,},}
。我完全可以使用这个数组/对象和键在KeyForm.js内部进行比较,但我真的希望在Database.js内部处理这个问题,并返回一个布尔值。有什么方法可以实现吗?ARg-当然-我已经从.once()返回了承诺
.DS有修复方法-为了完整性,我将在这里添加。我认为这很接近,但它会导致函数返回一个“Promise”对象而不是booleanYes。当然,这就是工作原理。要使用该值,请执行以下操作:isValidCode('stuff')。然后(result=>{/*use result here*/}
这肯定更接近,但它返回对象{“-LemIGLQEdkCniOFoi8d”:对象{“value”:“broIMI”,},“-LemIbAmrtC9ABe9EXM2”:对象{“value”:“7xMbif”,},}
。我肯定可以使用它