当前位置: 首页 > 知识库问答 >
问题:

为什么State总是空的?

相诚
2023-03-14

我已经彻底研究了所有的问题,但没有一个直接适用于我的问题。我正在循环访问用户ID数组并匹配它们以从我的firestore DB中获得一个用户。我会毫无问题地返回结果,但当我将其存储在状态数组中并运行控制台日志时,我的状态数组总是空的。第一个console.log工作并显示DB的结果。

const UsersScreen = (props) => {

    const [state, setState] = useState({
        users: []
    });  

    const getUserProfiles = () => {
        let users = [];
        //networkUsers is an array with the ids
        networkUsers.forEach(userId => { 
            db.doc(userId).get().then((doc) => {
                users.push(doc.data());
                console.log('localusers', users)
            }).catch((error) => {
                console.log('caught error', error)
            })
        });

        setState({ users: users });
    };


    useEffect(() => {
        getUserProfiles();
    }, []);

console.log('state', state.users)
}

请帮帮忙。

共有1个答案

班安平
2023-03-14

从Firestore获取文档的逻辑是异步的。但是,对setstate的调用是同步的。它将始终在获取文档之前。解决方案是获取文档,然后设置状态。这里有一个例子:

const UsersScreen = (props) => {
  const [state, setState] = useState({
    users: [],
  });

  const getUserProfiles = () => {
    Promise.all(networkUsers.map((userID) => db.doc(userId).get()))
      .then((docs) => {
        setState({ users: docs.map((doc) => doc.data()) });
      })
      .catch((err) => {
        console.log("caught error", error);
      });
  };

  useEffect(() => {
    getUserProfiles();
  }, []);

  console.log("state", state.users);
};

promise.all调用在从Firestore中提取每个用户后(也许您可以一次提取他们)就会解析。一旦有了用户,我们就用map对其进行循环,以提取文档的数据并设置状态。以下是async/await的替代方案:

const UsersScreen = (props) => {
  const [state, setState] = useState({
    users: [],
  });

  const getUserProfiles = async () => {
    try {
      const docs = await Promise.all(
        networkUsers.map((userID) => db.doc(userId).get())
      );

      setState({ users: docs.map((doc) => doc.data()) });
    } catch (err) {
      console.log("caught error", error);
    }
  };

  useEffect(() => {
    getUserProfiles();
  }, []);

  console.log("state", state.users);
};
 类似资料:
  • 问题内容: 在CSS中定义时,总是返回空。 但是,如果您在该元素中设置样式,则可以获取style.display详细信息。 我的问题不同。 内联样式不是编码的好方法。因此,我们总是在CSS中分配样式。但是,为什么在提供style属性而不是通过element 时却显示为空?JavaScript是否特别无法读取style属性? 您可以在下面检查,即使我提供了,所有样式属性都为空。 为什么? 问题答案:

  • 为什么数据段寄存器(ds/es/fs/gs)在GDB中总是显示为0x0?例如,无论我看哪个进程或线程,“info reg”似乎总是给我这样的输出: 我正在尝试调试glibc代码,在我正在分解的函数中看到fs段前缀: 我知道这就是glibc将如何引用线程的TCB(tcbhead_t)来获取TLS和其他重要内容。所以这不是意味着每个线程都需要一个唯一的描述符条目吗?每个线程不应该对fs寄存器有一个唯一

  • 问题内容: 我似乎无法弄清楚为什么我的JFrame为空。我要去哪里错了? 导入javax.swing。*; 导入java.awt.FlowLayout; 公共类GUIExample扩展JFrame { } 问题答案: 您忘记在jFrame中添加contentPane了,就像这样 我注意到您正在使用继承来构建jFrame,因此在这种情况下,您需要实例化自己的类。我已经用最小的代码重构了您的代码以运行

  • null Spring-web有没有可能在调用Jersey之前消耗InputStream? 请帮帮我. 编辑 我的回答是 芭芭拉 我的控制台输出是

  • 问题内容: 我有以下代码。应该返回表的最后一行的mysqli_insert_id()(在本例中为“ $ last_row”)始终返回0。为什么会这样呢? 问题答案: 并 没有 返回表的最后一排的ID。从文档中,它: …返回由查询产生的ID,该查询是对具有具有AUTO_INCREMENT属性的列的表进行的。如果最后一个查询不是or 语句,或者如果修改后的表没有带有属性的列,则此函数 将返回零 。 (

  • 问题内容: 我找到了JavaDoc的方法: 返回:如果此线程已被中断,则返回true;否则返回false。 否则为假。 我对这种方法的理解有误。此外,我可能会误解Thread中的“中断”概念。 欢迎任何解释!谢谢! 程式码片段: 在线程定义中: 调用: 问题答案: 引发异常后,线程不再处于中断状态。