开发者问题收集

React 应用程序中的自定义 Firebase 函数未返回值

2019-12-15
300

我为我的 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
  }
  ...

我尝试使用普通函数而不是箭头函数,但它不能解决问题。

1个回答

发生的事情是,您正在访问的 Firebase 方法是异步的,但您的代码忽略了这一点并期望它们同步工作。本质上,该函数将在等待异步操作解析时返回。

您调用 AuthState 。操作 firebase.auth().onAuthStateChanged 被触发,等待 Firebase 完成其任务并返回。在此之前,将执行函数中的其余行。没有,因此返回未定义。稍后,传递给 onAuthStateChanged 的​​回调被触发,但未绑定到任何内容,因此无法获得解析的返回值。

要在操作实际完成后触发某些代码,您可以更改代码以使用异步构造,无论是回调还是承诺。

回调:

const AuthState = (cb) => {
  firebase.auth().onAuthStateChanged(user => {
    if (user) {
      cb(user);
    } else {
     cb(null);
    }
  });
};

现在,将异步操作的时间与 React 的渲染方法集成起来会更复杂。不要将这样的异步代码放入 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)
      });
    }
  }
  ...
Jacob Penney
2019-12-15