【问题标题】:React not rendering after asynchronous assignment异步分配后反应不渲染
【发布时间】:2020-11-20 23:10:14
【问题描述】:

我很确定问题出在异步行为上。我认为这是因为我的反应应用程序在userLinks.exists 为真时有条件地呈现,但这只有在 firebase 方法完成后才会被分配。关于如何解决这个问题的任何建议?页面一直呈现空白屏幕并出现错误:

react-dom.development.js:13413 
Uncaught Error: Objects are not valid as a React child (found: [object Promise]). 
If you meant to render a collection of children, use an array instead.

app.js

const User = async ({ match, location }) => {

  const userLinks = await firebase.getUserInfo(match.params.user)

  return (
    <React.Fragment>
      { userLinks.exists ? <h1>Loaded and works!</h1> : <h1>Didn't work</h1> }
    </React.Fragment>

firebaseconfig.js

class Firebase {
  constructor() {
    firebase.initializeApp(firebaseConfig);
    this.auth = firebase.auth();
    this.db = firebase.firestore();
  }

  async getUserInfo (username) {
    let userInfo = { exists: false }
    await this.db.collection("users").doc(username).get().then(doc => {
      if (doc.exists) {
          console.log("Document data:", doc.data());
          userInfo.exists = true;
          userInfo = { ...userInfo, links: doc.data().links };
      } else {
          // doc.data() will be undefined in this case
        console.log("No such document!");
      }
    }).catch(function(error) {
        console.log("Error getting document:", error);
    });
    return userInfo;
  }

export default new Firebase();

【问题讨论】:

  • 错误提示你正在尝试渲染一个 Promise。 userLinks 的输出是什么?
  • @AdamAzad Ah 发现 userLinks 的输出是一个 ,但是如何获取这个 promise 的 .then() 值并及时更新到 react 组件呢?我应该像上面那样使用 useState 吗? (我更新了帖子)

标签: javascript firebase asynchronous google-cloud-firestore


【解决方案1】:

使用async / await 不会使代码突然同步运行。你仍然需要注意返回 Promise 和 values,并将它们冒泡。

在您的代码中,我认为应该是这样的:

  async getUserInfo (username) {
    return await this.db.collection("users").doc(username).get().then(doc => {
      if (doc.exists) {
        return { exists: true, links: doc.data().links };
      } else {
        return { exists: false }
      }
    }).catch(function(error) {
      console.log("Error getting document:", error);
    });
  }

【讨论】:

  • 嘿,谢谢你的回答,但它仍然给我同样的错误......虽然,现在如果我 .then() 我的 userLinks,它给了我正确的值,它只是永远不会更新常量时间。你知道为什么吗?我更新了帖子
  • 您需要在数据可用时检查组件是否仍然挂载。请参阅google.com/… 顺便说一句:像您一样更改您的问题并不常见,因为现在我的答案与问题不匹配 - 而实际上它解决了您最初的问题并将您转移到下一个问题。更常见的是添加新代码或(更好)为新问题打开一个新问题如果它在阅读一些搜索结果后仍然存在。
【解决方案2】:

await 等待解决或拒绝的承诺。 尝试 return Promise.resolve(userInfo);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-28
    • 2018-04-05
    • 2020-06-14
    • 2019-02-03
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多