我为我的react应用程序做了一些自定义的firebase函数,因此我不必每次都编写整个代码。问题是,当有一个要返回的值(例如用户JSON)时,当我从另一个文件调用时,它不会返回。
这是一段不起作用的代码:
Functions.js
import * as firebase from 'firebase'
const AuthState = () => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
return user;
} else {
return null;
}
});
};
export {AuthState}
我在我的React入口文件中称它为: App.js
import {AuthState} from './Functions'
class App extends Component {
componentDidMount() {
const result = AuthState();
console.log(result) // Undefined
}
...
我尝试使用普通功能而不是箭头功能,但是不能解决问题。
答案 0 :(得分:1)
正在发生的事情是您正在访问的firebase方法是异步的,但是您的代码会忽略该方法,并希望它们能够同步工作。本质上,该函数将在等待异步操作解决之前返回。
您致电AuthState
。触发操作firebase.auth().onAuthStateChanged
,等待firebase完成任务并返回。在此之前,将执行函数中的其余各行。没有,因此返回未定义。后来,触发了传递给onAuthStateChanged的回调,但没有绑定任何回调,因此解析的返回值不可访问。
要在操作实际完成后触发一些代码,可以将代码更改为使用异步构造(回调或promise)。
回调:
const AuthState = (cb) => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
cb(user);
} else {
cb(null);
}
});
};
现在,将异步操作的时间与React的render方法集成在一起是一件更复杂的事情。不要将类似的异步代码放入componentDidMount
属性中。这可能会导致无限的更新循环。而是在构造函数中进行初始化,或者在用户触发时进行调用(即单击按钮或按Enter键):
import {AuthState} from './Functions'
class App extends Component {
constructor(super) {
props(super)
this.state = {
result = null
}
// get the results of component render initialization:
AuthState(res => {
this.setState({
result: res
})
console.log(res)
});
// or you can wrap that in a function for attaching to DOM event listeners:
this.clickHandler = e => {
AuthState(res => {
this.setState({
result: res
})
console.log(res)
});
}
}
...