繁体   English   中英

如何将子集合中的数据分配到其集合并呈现新对象? 使用 react、firebase 和 useeffect-hook

[英]How to assign data from a subcollection to its collection and render the new object? Using react, firebase and useeffect-hook

我陷入了以下问题,经过大量研究后没有找到任何答案。

我想要做的是:简单地让用户从带有 react 和 useeffect-hook 的 firestore-DB 中包含他们的图像并显示它们。

DB 结构如下所示: https : //i.stack.imgur.com/sDcrv.png

所以图片是用户集合的子集合

从用户集合中获取用户后,我正在执行第二个请求,使用Object.assign将用户图像添加到该特定用户。 在每次对用户集合进行 forEach 运行后,我正在使用setUsers((oldUsers) => [...oldUsers, currentUser]);设置用户数组setUsers((oldUsers) => [...oldUsers, currentUser]); . 记录用户阵列显示使用包括他们的图像。

问题:当试图渲染图像时,它们总是未定义的。

解决方法:按下调用重新设置用户的功能的按钮:

const reRenderUsers = () => {
    if (userDataLoaded === false) {
      setUserDataLoaded(true);
    }
    const copy = [...users];
    setUsers(copy);
  };

^ 这解决了问题和显示的所有图像。

问题:是否有可能在不需要“重新渲染”用户的情况下立即显示图像? 例如,我是否错误地使用了 useEffect-hook? 我很感激任何建议。 提前谢谢了!

这里是完整的代码:

     const [users, setUsers] = useState([]);
     const [userDataLoaded, setUserDataLoaded] = useState(false);

     useEffect(() => {
       const unsubscribe = database.collection("users").onSnapshot((snapshot) => {
         snapshot.forEach((doc) => {
           const currentUser = {
             id: doc.id,
             ...doc.data(),
           };
           database
             .collection("users")
             .doc(currentUser.id)
             .collection("pictures")
             .get()
             .then((response) => {
               const fetchedPictures = [];
               response.forEach((document) => {
                 const fetchedPicture = {
                   id: document.id,
                   ...document.data(),
                 };
                 fetchedPictures.push(fetchedPicture);
               });
   
               currentUser.pictures = [];
               Object.assign(currentUser.pictures, fetchedPictures);
             })
             .catch((error) => {
               console.log(error);
             });
   
           setUsers((oldUsers) => [...oldUsers, currentUser]);
         });
       });
   
       return () => {
         unsubscribe();
       };
     }, []);
   
     const reRenderUsers = () => {
       if (userDataLoaded === false) {
         setUserDataLoaded(true);
       }
       const copy = [...users];
       setUsers(copy);
     };
   
     return (
       <div>
         {!userDataLoaded ? (
           <button onClick={reRenderUsers}> load users </button>
         ) : null}
   
         {users.map((user, index) => (
           <div key={user.id}>
             {user.pictures && <img src={user.pictures[0].imageUrl}></img>}
           </div>
         ))}
       </div>
     );
   }
   
   export default User;

这是因为您在 firebase 响应完成回调链之前调用 setUser。 您需要在成功回调内的循环完成后立即更新状态。 我已经更新 useEffect 以在回调后立即更新它

useEffect(() => {
  const unsubscribe = database.collection("users").onSnapshot((snapshot) => {
    snapshot.forEach((doc) => {
      const currentUser = {
        id: doc.id,
        ...doc.data(),
      };
      database
        .collection("users")
        .doc(currentUser.id)
        .collection("pictures")
        .get()
        .then((response) => {
          const fetchedPictures = [];
          response.forEach((document) => {
            const fetchedPicture = {
              id: document.id,
              ...document.data(),
            };
            fetchedPictures.push(fetchedPicture);
          });
          currentUser.pictures = fetchedPictures;
          setUsers((oldUsers) => [...oldUsers, currentUser]);
        })
        .catch((error) => {
          console.log(error);
        });
      //dont need this here
      //setUsers((oldUsers) => [...oldUsers, currentUser]);
    });
  });

  return () => {
    unsubscribe();
  };
}, []);

祝你好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM