Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将子集合中的数据指定给其集合并呈现新对象?使用react、firebase和useeffect挂钩_Javascript_Reactjs_Firebase_Google Cloud Firestore - Fatal编程技术网

Javascript 如何将子集合中的数据指定给其集合并呈现新对象?使用react、firebase和useeffect挂钩

Javascript 如何将子集合中的数据指定给其集合并呈现新对象?使用react、firebase和useeffect挂钩,javascript,reactjs,firebase,google-cloud-firestore,Javascript,Reactjs,Firebase,Google Cloud Firestore,我陷入了以下的困境,经过大量的研究还没有找到任何答案 我想做什么:简单地让用户使用react和useeffect挂钩从firestore DB中输入他们的图像并显示它们 数据库结构如下所示: 因此,这些图片是用户集合的子集合 在从users集合中获取用户之后,我将使用Object.assign再次请求将用户图像添加到此特定用户。每次forEach在users集合上运行之后,我都会使用setUsers((oldUsers)=>[…oldUsers,currentUser])设置users数组。记

我陷入了以下的困境,经过大量的研究还没有找到任何答案

我想做什么:简单地让用户使用react和useeffect挂钩从firestore DB中输入他们的图像并显示它们

数据库结构如下所示:

因此,这些图片是用户集合的子集合

在从users集合中获取用户之后,我将使用Object.assign再次请求将用户图像添加到此特定用户。每次forEach在users集合上运行之后,我都会使用
setUsers((oldUsers)=>[…oldUsers,currentUser])设置users数组。记录用户阵列将显示包括其图像在内的使用情况

问题:在尝试渲染图像时,图像始终未定义

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

const reRenderUsers = () => {
    if (userDataLoaded === false) {
      setUserDataLoaded(true);
    }
    const copy = [...users];
    setUsers(copy);
  };
^这就解决了问题,并解决了所有显示的图像

问题:是否有可能在不需要“重新渲染”用户的情况下立即显示图像?例如,我是否使用了useEffect挂钩错误?我很感谢你的建议。非常感谢

以下是完整的代码:

     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;
const[users,setUsers]=useState([]);
const[userDataLoaded,setUserDataLoaded]=useState(false);
useffect(()=>{
const unsubscribe=database.collection(“用户”).onSnapshot((快照)=>{
snapshot.forEach((doc)=>{
const currentUser={
id:doc.id,
…doc.data(),
};
数据库
.收集(“用户”)
.doc(currentUser.id)
.收藏(“图片”)
.get()
。然后((响应)=>{
常量fetchedPictures=[];
response.forEach((文档)=>{
常量fetchedPicture={
id:document.id,
…document.data(),
};
fetchedPicture.push(fetchedPicture);
});
currentUser.pictures=[];
分配对象(currentUser.pictures、fetchedPictures);
})
.catch((错误)=>{
console.log(错误);
});
setUsers((oldUsers)=>[…oldUsers,currentUsers]);
});
});
return()=>{
取消订阅();
};
}, []);
常量重新渲染器=()=>{
如果(userDataLoaded==false){
setUserDataLoaded(true);
}
const copy=[…用户];
setUsers(副本);
};
返回(
{!userDataLoaded(
加载用户
):null}
{users.map((用户,索引)=>(
{user.pictures&&}
))}
);
}
导出默认用户;

这是因为您在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();
  };
}, []);

祝你好运

非常感谢!这正是我想要的:)