我已经彻底解决了所有提出的问题,但没有一个直接适用于我的问题。我正在遍历用户ID数组并对其进行匹配,以从我的Firestore数据库中获取用户。我得到的结果没有问题,但是当我将其存储在状态数组中并运行控制台日志时,我的状态数组始终为空。第一个console.log起作用并显示数据库的结果。
这是我的代码:
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)
}
请帮助。
答案 0 :(得分:4)
从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);
};
一旦从Firestore中提取了每个用户,Promise.all
调用便会解析(尽管您可以一次提取它们)。一旦有了用户,就可以使用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);
};